Ng5 Karma Jasmine测试渲染组件而不是结果页面

Ng5 Karma Jasmine测试渲染组件而不是结果页面

问题描述:

假设我有一个非常简单的创建"单元测试,该类型是ng cli为您生成的:

Let's say i have a very simple 'create' unit test, kind that ng cli generates for you:

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyComponent],
      imports: [
        HttpClientTestingModule,
        FormsModule,
        RouterTestingModule.withRoutes([{ path: 'home', redirectTo: '/' }])
      ],
      providers: [SomeService1, SomeService2, { provide: SomeService3, useValue: {} }],
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

现在,当我像这样ng test --browser=Chrome进行此测试时,而不是查看Karma结果页面,而是查看我的组件.

Now when i run this test like so ng test --browser=Chrome instead of looking at Karma results page, i am looking at my component.

我的CLI版本是1.6.3,业力1.7.1,Angular 5.2.0,操作系统macOS.

My CLI version is 1.6.3, Karma 1.7.1, Angular 5.2.0, OS macOS.

更新我的浏览器被捕获,业力加载,测试运行,但我看到的是全屏组件,而不是业力结果,因为它的css覆盖了它们的结果.如果找到div并将其在DOM中删除,则可以看到Karma结果.

Update My browser is captured, karma loads, tests run but instead of karma results i see my full-screen component because it's css overlays their results. If i find the div and delete it in the DOM, i can see Karma results.

我只是希望Angular删除该节点.

I was just expecting Angular to remove that node.

我不太确定为什么在测试结束后仍保留该组件的DOM编译,但是我注意到它仅在上一次运行的测试中发生.如果您可以添加另一个也可以编译一个组件但不添加全屏组件的组件测试,则可以正确删除前一个组件.因此,简单地添加更多测试可能是最简单的解决方案.

I am not really sure why the DOM compilation of the component stays after the test ends, but I noticed it happens only for the last test that ran. If you can add another component test that also compiles a component but doesn't add a full-screen component, the previous one is correctly removed. So, simply adding more tests could be the easiest solution.

但是,如果这还不够的话,这里有两种可能的解决方案:

But if that's not enough, here goes two possible solutions:

如果您的测试不涉及验证结果DOM,则可以直接使用该组件来简化测试的安排.

If your tests don't involve verifying the resulting DOM, you can simplify the arrangement of your test by using the component directly.

describe('MyComponent', () => {
  TestBed.configureTestingModule({
    // declarations: [MyComponent],
    imports: [
      HttpClientTestingModule,
      FormsModule,
      RouterTestingModule.withRoutes([{ path: 'home', redirectTo: '/' }]),
    ],
    // 1. Add the component as a provider.
    providers: [MyComponent, SomeService1, SomeService2, { provide: SomeService3, useValue: {} }],
    schemas: [NO_ERRORS_SCHEMA],
  });

  it('should do thing #1', () => {
    // 2. Test it like you would test a service.
    const comp = TestBed.get(MyComponent);
    expect(comp.value).toBe(false, 'off at first');
    comp.doThing1();
    expect(comp.value).toBe(true, 'on after click');
    comp.doThing1();
    expect(comp.value).toBe(false, 'off after second click');
  });

  it('should do thing #2', () => {
    const comp = TestBed.get(MyComponent);
    expect(comp.value2).toMatch(/is off/i, 'off at first');
    comp.doThing2();
    expect(comp.value2).toMatch(/is on/i, 'on after clicked');
  });
});

更多信息此处.

如果您确实需要测试DOM,我发现的唯一解决方法是在完成测试后显式删除HTML元素.

If you do need to test the DOM, the only workaround I have found is to explicitly remove the HTML element after finishing the tests.

  afterEach(() => {
    if (fixture.nativeElement && 'remove' in fixture.nativeElement) {
      (fixture.nativeElement as HTMLElement).remove();
    }
  });