【问题标题】:Running jasmine tests for a component with NgZone dependency为具有 NgZone 依赖项的组件运行 jasmine 测试
【发布时间】:2018-05-10 05:27:14
【问题描述】:

我将如何继续为以下组件运行 jasmine 测试:

@Component({
  moduleId: module.id,
  selector: "testComp",
  template: "<div>{{value}}</div>",
})
export class TestComp {
  public value: string = "This is me";
  constructor(public zone: NgZone) {
    this.zone.run(() => console.log("zone is here"));
  }
}

以下失败并显示无法解析 NgZone 的所有参数:

describe("test", () => {
    let fixture;
    let component;

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [TestComp],
        schemas: [NO_ERRORS_SCHEMA],
        providers: [NgZone]
    }).compileComponents;
}));
beforeEach(() => {
    fixture = TestBed.createComponent(TestComp);
    component = fixture.debugElement.componentInstance;
});
it("should check that the component is created", () => {
    expect(component).toBeTruthy();
});

})

使用 Angular 4.1.3。我找到了 MockNgZone 类 @https://no-shadow-angular-io.firebaseapp.com/docs/ts/latest/api/core/testing/MockNgZone-class.html。但在这个特定版本的@angular/core/testing 中似乎不可用:

有人知道我应该怎么做来测试这个组件吗?

问候

【问题讨论】:

    标签: angular jasmine ngzone


    【解决方案1】:

    如果您的问题与runOutsideAngular 相关,因为您不能使用asyncfakeAsync,那么您唯一需要模拟的就是该函数,并且以下内容运行良好:

    const ngZone = TestBed.get(NgZone);
    
    spyOn(ngZone, 'runOutsideAngular').and.callFake((fn: Function) => fn());
    

    【讨论】:

      【解决方案2】:

      在 Angular 5.2.4(通过 Angular CLI 1.6.8 安装)中,mock 已从代码库中删除,因此无需在 Jasmine 中使用它。只需跳过提供者列表中的 NgZone 声明即可。

      【讨论】:

      • 在我从providers 中删除NgZone 之前,我遇到了很多错误。谢谢!
      【解决方案3】:

      这有点神秘,MockNgZone 仍在源代码中,但已从公共 API 中删除。

      鉴于 mock run() 的简单实现

      export class MockNgZone extends NgZone {
        ...
        run(fn: Function): any { return fn(); }
      

      我会用它来帮助你度过难关

      const mockNgZone = jasmine.createSpyObj('mockNgZone', ['run', 'runOutsideAngular']);
      mockNgZone.run.and.callFake(fn => fn());
      
      TestBed.configureTestingModule({
        ...
        providers: [
          { provide: NgZone, useValue: mockNgZone },
        ]
      

      【讨论】:

      • 我收到 TypeError: Cannot read property 'subscribe' of undefined
      【解决方案4】:

      我也有类似的要求,我就是这样做的,

      TestBed 配置,

      beforeEach(() => {
          TestBed.configureTestingModule({
              imports: [
                  // Specify imports
              ],
              providers: [
                  { provide: DependentService, useValue: dependentServiceSpy }
                  // Do not provide NgZone here
              ]
          });
          guard = TestBed.inject(ARouteGuard);
      });
      

      请注意,我没有在 providers 数组中指定 NgZone

      这就是我的测试的样子,

      it('should be created', () => {
          let zone = TestBed.get(NgZone);
          spyOn(zone, 'run').and.callFake((fn: Function) => fn());
          
          // Implement your test and expectations
      
          expect(guard).toBeTruthy();
      });
      

      我不得不从 providers: [ ] 数组中删除 NgZone 或其对应的模拟对象,因为它引入了其他错误,例如 “无法解析 NgZone 的所有参数”“无法读取未定义的属性订阅”。

      【讨论】:

        【解决方案5】:

        我们有同样的问题,完全一样。 最后,我们保留了 ngZone,并确保我们测试了它使用的回调。

        beforeEach(async(() => {
        TestBed.configureTestingModule({
            ...
            providers: [NgZone]
          })
        }));
        

        对于使用 ngZone 的代码,例如

        zone.run(someFunction)
        

        我们确保通过单元测试获得良好的测试覆盖率someFunction

        【讨论】:

        • 如果检查组件测试已经失败,你如何测试 someFunction?我和安德烈有同样的问题
        • 在常规 js 模块中使其成为纯函数。为模块编写测试。将其导入组件中。
        猜你喜欢
        • 2017-09-05
        • 2019-01-09
        • 1970-01-01
        • 1970-01-01
        • 2015-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-20
        相关资源
        最近更新 更多