Angular - 为什么我的弹珠测试不适用于包含用户权限的BehaviorSubject?

2023-12-13

我正在使用 Angular 8 编写一个应用程序。

我决定使用带有BehaviorSubject 的 rxjs 存储来进行简单的状态管理。

基本上,我的代码是一个存储、加载和更新用户权限的服务。有时,此信息将在 HTTP 调用后来自服务器,有时此信息将来自本地存储。用户权限更改后,所有订阅者都会得到更新。

这是我的 StackBlitz:https://stackblitz.com/edit/rxjs-state-management-get-set 请单击“添加配置文件”按钮以查看其实际效果。

这是我设置了单元测试的 StackBlitz:https://stackblitz.com/edit/rxjs-state-management-get-set-xpptmr

我已经使用基本的订阅者和完成技术编写了一些单元测试,但我想更深入地挖掘。

我读到我们可以使用“弹珠”来测试 Observable 随着时间的推移的价值:https://rxjs-dev.firebaseapp.com/guide/testing/internal-marble-tests

我想使用弹珠来测试代码中的“加载”功能。

服务存储的代码片段:

@Injectable({
    providedIn: 'root'
})
export class PersonaService {

    private readonly data: BehaviorSubject<IPersonaData>;
    public readonly sharedData: Observable<IPersonaData>;

    constructor() {
        this.data = new BehaviorSubject<IPersonaData>(null);
        this.sharedData = this.data.asObservable() as Observable<IPersonaData>;
    }
   
    public load(): void {

        const storedPersonaData: IPersonaData = {
            currentPersonaIndex: null,
            personas: []
        };

        const storedCurrentIndex: string = localStorage.getItem(Constants.KEYS.defaultPersonaIndex) as string;

        if (storedCurrentIndex != null) {
            storedPersonaData.currentPersonaIndex = parseInt(storedCurrentIndex, Constants.RADIX.BASE_10);
        }

        const storedPersonas: string = localStorage.getItem(Constants.KEYS.personas) as string;

        if (storedPersonas != null) {
            storedPersonaData.personas = JSON.parse(storedPersonas) as IPersona[];
        }

        this.data.next(storedPersonaData);
    }

    public clear(): void {
        this.data.next(null);
    }

}

基本上,“加载”函数检查本地存储中是否存储了任何数据,如果有,它将更新BehaviorSubject 值。我想测试该值如何随时间变化,例如在调用加载函数之前它是值 1,而在调用该函数之后它不是值 2。

03/07/2020 尝试弹珠测试 ---- 编辑:

这是我的弹珠测试的代码片段:

  fit("clear", () =>
    testScheduler.run(({ expectObservable }) => {
      const newPersonaData: IPersonaData = {
        currentPersonaIndex: 1,
        personas: [...mockPersonas] //TODO: is this the best way to make a copy of it???
      };

      //put the data in the behaviour subject first
      localStorage.setItem(
        Constants.KEYS.defaultPersonaIndex,
        newPersonaData.currentPersonaIndex.toString()
      );
      localStorage.setItem(
        Constants.KEYS.personas,
        JSON.stringify(newPersonaData.personas)
      );
       
      //service.sharedData - initial value should be null
      service.load(); //service.sharedData - value should be newPersonaData

      service.clear(); //service.sharedData - value should be null

      expectObservable(service.sharedData).toBe("abc", {
        a: null,
        b: newPersonaData,
        c: null
      });
    }));

Error:

finished in 0.368sRan 1 of 9 specs - run all1 spec, 1 failure, randomized with seed 98448Spec List | FailuresSpec List | Failures
PersonaService > clear
Expected $.length = 1 to equal 3. Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: Object({ currentPersonaIndex: 1, personas: [ Object({ PersonaId: 154, Current: true, Description: 'Employee', SecuritySelectionId: 804356, DefaultSelectionId: 0, ProfileId: 17, ProfileName: '', IsSingleEmployee: true, DefaultEmpId: 714, EmpNo: '305', Level: -2, LevelDescription: 'Employee 1', AccessBand: 0, AuthBand: 0, PersonaIndex: 0, ExpiryDate: ' ', CoveringUserName: '', CoveringStartDate: ' ', CoveringEndDate: ' ', mobileaccess: true, canclock: true, mustsavelocation: true, canbookholiday: true, viewroster: true, canbookabsence: true, canviewbalancedetails: true, canviewactivity: true, canviewtimesheet: false, canviewtimesheetapproval: false, View_Shift_Swap: false, View_Flexi: true, View_Team_Calendar: false, Cancel_Absence: true, Delete_Absence: false, Mobile_Upload_Photo: true, Mobile_Upload_Absence_Photo: true, Receive_Notifications: false, CanViewRosterV2: false, AbsenceActions: [ Object({ .... Expected $[2] = undefined to equal Object({ frame: 2, notification: Notification({ kind: 'N', value: null, error: undefined, hasValue: true }) }).
Error: Expected $.length = 1 to equal 3. Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: Object({ currentPersonaIndex: 1, personas: [ Object({ PersonaId: 154, Current: true, Description: 'Employee', SecuritySelectionId: 804356, DefaultSelectionId: 0, ProfileId: 17, ProfileName: '', IsSingleEmployee: true, DefaultEmpId: 714, EmpNo: '305', Level: -2, LevelDescription: 'Employee 1', AccessBand: 0, AuthBand: 0, PersonaIndex: 0, ExpiryDate: ' ', CoveringUserName: '', CoveringStartDate: ' ', CoveringEndDate: ' ', mobileaccess: true, canclock: true, mustsavelocation: true, canbookholiday: true, viewroster: true, canbookabsence: true, canviewbalancedetails: true, canviewactivity: true, canviewtimesheet: false, canviewtimesheetapproval: false, View_Shift_Swap: false, View_Flexi: true, View_Team_Calendar: false, Cancel_Absence: true, Delete_Absence: false, Mobile_Upload_Photo: true, Mobile_Upload_Absence_Photo: true, Receive_Notifications: false, CanViewRosterV2: false, AbsenceActions: [ Object({ .... Expected $[2] = undefined to equal Object({ frame: 2, notification: Notification({ kind: 'N', value: null, error: undefined, hasValue: true }) }). at <Jasmine> at TestScheduler.deepEqual [as assertDeepEqual] (https://rxjs-state-management-get-set-xpptmr.stackblitz.io/~/src/testing/persona.service.spec.ts:8:20) at eval (https://rxjs-state-management-get-set-xpptmr.stackblitz.io/turbo_modules/[email protected]/internal/testing/TestScheduler.js:133:23) at <Jasmine>

例子:


我们需要做的是使用 ReplaySubject 来捕获 Observable 拥有的所有值。 如果我们使用 BehaviourSubject,它只会给我们最终值,而不是过去的所有值。

example:

it('2a clear - should clear the data from the BehaviorSubject - should be null, data, null', () => testScheduler.run(({ expectObservable }) => {

    const replaySubject$ = new ReplaySubject<IPersonaData>();
    service.sharedData.subscribe(replaySubject$);

    const newPersonaData: IPersonaData = {
        currentPersonaIndex: 1,
        personas: [...mockPersonas] //TODO: is this the best way to make a copy of it???
    };

    //put the data in the behaviour subject first
    appSettings.setString(Constants.KEYS.defaultPersonaIndex, newPersonaData.currentPersonaIndex.toString());
    appSettings.setString(Constants.KEYS.personas, JSON.stringify(newPersonaData.personas));

    service.load();
    service.clear();

    expectObservable(replaySubject$).toBe('(abc)', { a: null, b: newPersonaData, c: null });

}));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular - 为什么我的弹珠测试不适用于包含用户权限的BehaviorSubject? 的相关文章

  • Angular 4 中的箭头函数(Lambda 函数)

    我对lambda知之甚少 lambda表达式被视为一个函数 我们有很多方法可以做到这一点 这是我的简单功能TypeScript file byPan card1 card2 return card1 pan card2 pan 我在 HTM
  • Angular AOT 和 Rollup - 无法解析“app.module.ngfactory”

    我正在尝试完成 Angular 的 AOT 教程 https angular io docs ts latest cookbook aot compiler html https angular io docs ts latest cook
  • Angular 2发送数组另一页

    我正在使用 Angular 开发天气应用程序 我是 Angular 的新手 我想带上我选择的城市的天气信息 但我无法将数据发送到第二页 哪里有问题 预先感谢您的帮助 export class ForecastComponent implem
  • Angular2 如何对自定义验证器指令进行单元测试?

    我为输入字段编写了一个非常简单的自定义验证器 import Directive from angular core import AbstractControl NG VALIDATORS from angular forms functi
  • 使用 QTestLib 时抑制 qDebug

    我正在向 Qt 中的项目添加单元测试 并希望使用 QTestLib 我已经设置了测试并且它们运行良好 问题是在项目中我们重写了 qDebug 以输出到我们自己的日志文件 这在运行应用程序时效果很好 问题是当我测试类时 它有时会开始记录 然后
  • 拖动事件未以角度 2 触发

    我有一个画布 我希望用户能够在其周围拖动图形元素 因此 我不希望画布本身拖动 但我想在鼠标执行这些操作时处理 Dragstart 拖放事件 我正在使用 Angular 2 所以我有 div div 然后在 editor component
  • 包括 PHPUnit 在内的麻烦

    我想开始为我的代码编写测试 因此我使用以下命令安装了最新的 PHPUnit wget http pear phpunit de get phpunit phar chmod x phpunit phar mv phpunit phar us
  • 通过 Angular 2 中的输入装饰器使用多个属性

    我有一个通过其选择器接收两个输入的组件 但这可以扩展到任意数量的输入和任何组件 因此 为了消耗组件本身的多个属性 Input 装饰器不允许我使用多个属性 因此作为解决方法 我对两个输入属性使用了两个装饰器 但我认为这不是解决这种情况的唯一方
  • 对自定义打字稿错误实例实施instanceof检查?

    打字稿有这个instanceof 检查自定义错误 https github com Microsoft TypeScript issues 13965问题 但尚不清楚我们需要做什么才能得到instanceof在职的 例如对于这个异常我们如何
  • pydev 断点不起作用

    我正在使用 python 2 7 2 sqlalchemy 0 7 unittest eclipse 3 7 2 和 pydev 2 4 开发一个项目 我在 python 文件 单元测 试文件 中设置断点 但它们被完全忽略 之前 在某些时候
  • Angular 7 SSR 第一次加载两次

    我内置了几个网站Angular 7 with SSR for SEO改进 所有应用程序本身都很好 但总是会发生这样的情况 第一次或者当您执行硬刷新有这个小blip由此显示所有内容并突然网站本身 重新加载 所有条件为ngIf可能隐藏在中评估的
  • 如何通过角度2中的父组件将自定义(html)模板传递给子组件?

  • 保持 mat-menu 打开角度

    我正在尝试在菜单中使用复选框选项 但我需要保持菜单打开 直到用户完成选择选项 我正在使用最新版本的 Angular 先感谢您 我已经组合了嵌套的垫菜单here https material angular io components men
  • Angular Serverless 部署到 AWS 将 base-href 附加到 url,导致重定向到 404 错误

    我正在尝试将 Angular 7 网站部署到 aws 无服务器上 作为新手 我遵循了本教程 https coursetro com posts code 165 Deploying your Angular App to a Serverl
  • C# .NET 4.0 测试框架?

    如果我没记错的话 NUnit 是单元测试事实上的标准 但我刚刚下载了它 编写了一个简单的测试 然后显然我必须启动 GUI 并加载我的 exe组装 根本就失败了 我尝试编辑 C Program Files x86 NUnit 2 5 7 bi
  • 在 angular2 视图模板中传递枚举

    我们可以在 angular2 视图模板中使用枚举吗 div class Dropdown div 传递字符串作为输入 enum DropdownType instrument account currency Component selec
  • 使用带有 RC5 的 Angular2 AoT ngc 编译器获取“无法读取 null 的属性‘类型’”

    更新到 Angular2 2 0 0 rc 5 在浏览器中运行时没有任何警告 但是当尝试使用 AOT 编译时ngc p命令 得到以下错误 这是我的项目https github com beginor learning angular2 ht
  • Material.Angular.io mat-autocomplete [displayWith] 函数更新范围变量

    我遇到了一个问题 我可以在实例化 mat autocomplete 的组件控制器中访问本地声明的变量 我面临的问题是局部变量被困在这个范围内 我无法更新它们 有关更新 mat autocomplete 范围变量的任何想法或想法 最终我要做的
  • Angular 5 表单验证(必需)不起作用

    我正在使用 TypeScript 学习 Angular 5 我对此完全陌生 我现在正在尝试构建一个表单并验证它 但它无法正常工作 这是我的组件 Component selector app login templateUrl login c
  • Angular 2在两个组件之间传递数据

    我想在两个组件之间传递数据 但我的问题是 我有两个组件 假设一个是 主 另一个是 模态对话框 在我的主要部分中 我想打开模态对话框并从模态对话框中获取数据 而无需离开我的主要组件 我知道如何使用 Input 但我看不到在我的应用程序中使用它

随机推荐

  • 丰富的数据表不能使用迭代变量进行嵌套循环

    我正在构建一个包含动态数量列的丰富数据表 在我看来 这不是什么大事 但我几个小时以来一直在试图得到答案 问题是当我想使用数据表中的迭代变量进行嵌套循环时 在嵌套循环中 我尝试为每一行创建相同的动态数量的列 当我展示一些代码时 可能会变得更清
  • 发送 url 但停留在同一页面( php、codeigniter、javascript )

    这就是我的情况 我正在 codeigniter 中编写一个 Web 界面 以将命令发送到虚拟服务器 这些命令通过浏览器以 url 的形式传递 例子 然后该服务器采取行动 并且 Web 界面刷新屏幕截图 我只想在 html 中有一堆链接 将这
  • 如何引用javadoc中的方法?

    我怎样才能使用 link标签链接到方法 我想改变 Returns the Baz object owned by the Bar object owned by Foo owned by this A convenience method
  • 为什么 dotnet test project.csproj --filter Category=unit 在 Azure DevOps 中失败?

    我的解决方案是在 Azure DevOps 中构建的 由于该解决方案具有单元和集成测试 我需要进行过滤以避免总是编辑构建定义 在我的笔记本电脑上 以下命令运行良好并且仅执行我需要的测试 dotnet test project csproj
  • mysql PDO和存储过程动态SQL注入

    正如我在许多帖子中所看到的 存储过程中的动态 SQL 很容易受到 SQL 注入的攻击 但是如果我们使用之前的 PDO 和准备好的语句 这仍然不安全吗 Example CREATE PROCEDURE my sp IN in var VARC
  • 如何在 Google 电子表格中搜索并查找行的坐标

    我已经搜索了很长一段时间 希望没有其他人问过这个问题 我有一个包含两张表的 Google 电子表格 一张是包含表单提交的数据库 另一张是用户一次与提交交互的方式 基本上 我希望用户能够对提交进行更改并将其保存回原始工作表中的同一行 我有发送
  • Scala:将映射转换为案例类

    假设我有这个示例案例类 case class Test key1 Int key2 String key3 String 我有一张地图 myMap Map k1 gt 1 k2 gt val2 k3 gt val3 我需要在代码的几个地方将
  • 固定标题 Flex Table - 标题垂直对齐

    jsFiddle https jsfiddle net 24by5tmv 1 我有一个简单的弹性表格 可以修复标题并滚动表格主体 但我想垂直对齐每个单元格内的内容 标题和主体 的中心 中间 将单元格设置为vertical align mid
  • 使用 PDO::FETCH_CLASSTYPE 传递构造函数参数

    我正在用基于 PDO 的新版本替换旧数据库层 但是我遇到了一个问题 当使用获取对象时fetchObject我可以传递对象构造函数的参数 但是我现在正在移植一个具有多个子类的类 所有子类都存储在同一个表中 并且我想使用FETCH CLASST
  • jQuery 按 div 高度分页(不是项目)

    我有兴趣使用 jQuery 根据内容和 div 的高度 而不是根据项目数量 创建自动分页 我能找到的大多数分页示例都是基于要分页的项目数量 而不是包含的 div 的高度和内容的高度 该解决方案不适用于不同长度的内容 有谁知道现有的解决方案可
  • 从 Android 终端禁用设备所有者应用程序

    好吧 我的问题是 我有一个应用程序被设置为设备 在本例中是我的平板电脑 的设备所有者 我从 Ubuntu 的终端执行此操作 将平板电脑连接到我的 PC 并在 adb shell 中执行此行 dpm set device owner my a
  • 将 spring-boot 应用程序部署为专用 tomcat 上的 war 文件不起作用

    我有一个 spring boot 应用程序 现在我想将该应用程序部署在专用 tomcat 服务器上 而不是使用嵌入式 tomcat 两种部署方式我都没有收到任何错误 我已经给出了范围 提供为了spring boot 启动器 tomcat依赖
  • jQuery .height() 在 Safari 中错误

    我在读出 a 的正确高度时遇到问题DIV在 Safari 中使用 jQuery 我在用jQuery x height 读出元素的高度 在实际情况中 我稍后在页面中使用结果 它在 Chrome Firefox 和 IE 中运行良好 但在 Sa
  • SVG 元素在 Safari 中不显示

    我在 html5 文档中有一些内联 svg 如下所示 div div
  • x86 汇编添加不同大小的操作数

    我喜欢将一个字节从内存位置添加到 32 位寄存器 这在 x86 汇编中可能吗 add edx byte ebx causes error mismatch in operand sizes 您需要确保操作数的大小相同 但这涉及到标志的问题
  • 如何使用 Aurelia/Typescript 导入 Moment-Timezone

    我已经正确导入了 momentjs 它工作正常 但是当我尝试导入时刻时区时 我无法让它工作 我无权访问任何功能 这是我的 aurelia json 文件 我从 npm 加载它们 name moment path node modules m
  • 带有右箭头的 github 存储库文件夹是什么意思?

    我有一个带有蓝色图标的 github 存储库文件夹 其中有一个向右箭头 我一直无法找到任何对 github 图标图例 键的引用 知道这个图标是什么吗 该图标表示git 子模块 它有另一个 git 版本控制项目 存储库的提交的链接 您可以阅读
  • CakePHP 单元测试中电子邮件中的完整 URL

    我想获得由我在 CakePHP 3 2 中的测试触发的电子邮件中的完整 URL 我尝试了完整的选项 this gt Html gt image image jpg fullBase gt true and this gt Url gt bu
  • 无法使用 java API (oAuth2) 将视频上传到 youtube。收到 403 访问禁止。该请求可能未得到正确授权

    我有一个将视频上传到 YouTube 的应用程序 自 2 月 24 日以来 我的应用程序在上传功能方面出现了严重问题 我正在使用 YouTube 的官方 google java 客户端 以及 oauth 我收到的问题403 Forbidde
  • Angular - 为什么我的弹珠测试不适用于包含用户权限的BehaviorSubject?

    我正在使用 Angular 8 编写一个应用程序 我决定使用带有BehaviorSubject 的 rxjs 存储来进行简单的状态管理 基本上 我的代码是一个存储 加载和更新用户权限的服务 有时 此信息将在 HTTP 调用后来自服务器 有时