对具有NgZone依赖关系的组件运行茉莉花测试

And*_*rey 5 jasmine angular ngzone

我将如何对以下组件进行茉莉花测试:

@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"));
  }
}
Run Code Online (Sandbox Code Playgroud)

由于无法解析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();
});
Run Code Online (Sandbox Code Playgroud)

})

使用Angular 4.1.3。我发现了MockNgZone类@ https://no-shadow-angular-io.firebaseapp.com/docs/ts/latest/api/core/testing/MockNgZone-class.html。但是对于此特定版本,在@ angular / core / testing中似乎不可用: 在此处输入图片说明

有人知道我应该怎么做才能测试此组件吗?

问候

小智 7

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


Ric*_*sen 6

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

给出了模拟run()的简单实现

export class MockNgZone extends NgZone {
  ...
  run(fn: Function): any { return fn(); }
Run Code Online (Sandbox Code Playgroud)

我会用它来帮助你克服困难

const mockNgZone = jasmine.createSpyObj('mockNgZone', ['run', 'runOutsideAngular']);
mockNgZone.run.and.callFake(fn => fn());

TestBed.configureTestingModule({
  ...
  providers: [
    { provide: NgZone, useValue: mockNgZone },
  ]
Run Code Online (Sandbox Code Playgroud)

  • 我收到 TypeError:无法读取未定义的属性“订阅” (5认同)

max*_*992 6

如果您的问题是runOutsideAngular因为无法使用asyncfakeAsync,那么您唯一需要模拟的就是该函数,以下代码可以很好地工作:

const ngZone = TestBed.get(NgZone);

spyOn(ngZone, 'runOutsideAngular').and.callFake((fn: Function) => fn());
Run Code Online (Sandbox Code Playgroud)


Har*_*riV 6

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

测试床配置,

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

请注意,我没有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();
});
Run Code Online (Sandbox Code Playgroud)

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


小智 0

我们确实有同样的问题。最后,我们保持 ngZone 不变,并确保我们测试它使用的回调。

beforeEach(async(() => {
TestBed.configureTestingModule({
    ...
    providers: [NgZone]
  })
}));
Run Code Online (Sandbox Code Playgroud)

对于使用 ngZone 的代码,例如

zone.run(someFunction)
Run Code Online (Sandbox Code Playgroud)

我们确保someFunction单元测试具有良好的测试覆盖率。