Angular2/Jasmine的Expect to be null会导致浏览器崩溃。

4

我在测试我的一个组件时遇到了一些问题。测试如下:

describe('SmpEventsNewCompactEventComponent', () => {

  const specService: SmpSpecService = new SmpSpecService();

  describe('Component rendering', () => {
    let componentInstance: any;
    let componentFixture: ComponentFixture<any>;
    let cssSelector: string;

    beforeEach(() => {
      TestBed.configureTestingModule({
        imports: [
          MaterialModule.forRoot()
        ],
        declarations: [
          SmpEventsCompactEventComponent,
          SmpEventsAddressComponent
        ],
        providers: [
          { provide: SMP_OT_HELPER, useValue: newOtHelperInstance() },
          DatePipe,
          SmpEventTypeCheckerService,
          SmpLangService
        ]
      });

      componentFixture = TestBed.createComponent(SmpEventsCompactEventComponent);
      componentInstance = componentFixture.componentInstance;
    });

    describe('Global', () => {
      it('GIVEN there are date/time AND address ' +
        'WHEN component loads THEN display event', () => {
          //// TEST ONE
          componentInstance.isEventEnabled = true;
          cssSelector = '.events-compact-event';

          let debugElement = specService.queryDebugElement(
            componentFixture, cssSelector);

          expect(debugElement).not.toBeNull();
        });

      it('GIVEN there are no date/time AND no address ' +
        'WHEN component loads THEN do not display event', () => {
          //// TEST TWO
          componentInstance.isEventEnabled = true;
          //componentInstance.isAddressEnabled = false;
          // componentInstance.isDateEnabled = false;
          cssSelector = '.events-compact-event';

          let debugElement = specService.queryDebugElement(
            componentFixture, cssSelector);

            console.log('--------------', debugElement.nativeElement);
          // expect(debugElement.nativeElement).toBe(null);
          // expect(true).toBe(true);
          expect(debugElement).not.toBeNull();
        });
    });
});

specService.queryDebugElement的使用方法如下:

  queryDebugElement(fixture: ComponentFixture<any>, cssSelector: string): DebugElement {
    fixture.detectChanges();

    return fixture.debugElement.query(By.css(cssSelector));
  }

Whenever i use the

expect(true).toBe(true);

或者
expect(debugElement.nativeElement).toBe(null);

或者

expect(debugElement).not.toBeNull();

在测试二中,测试通常可以正常工作或失败,但每当我使用

标签时,会出现问题。
expect(debugElement).toBeNull();

Karma使用的浏览器(已在Chrome / Chromium / PhantomJs中测试)崩溃并且没有给出任何提示。这不是简单的"期望false为true"失败,测试环境完全崩溃。

您看到了什么可以解释这种行为的东西吗?

4个回答

7
Angular的DebugElement是一个相当复杂的对象,Jasmine的expect似乎包含了递归部分(或者至少是足够复杂需要许多不同的函数调用的算法)……因此,在单元测试中直接使用DebugElement并不被推荐。这通常会导致深度递归和浏览器内存泄漏。
在您的情况下,我建议尝试:
let nl: NodeList = componentFixture.nativeElement.querySelectorAll('.events-compact-event');

expect(nl.length).toBeFalsy;

这样,您就不需要使用DebugElement,并且在测试中不会有未定义的值(除了需要为undefined的值)。代码覆盖率和结果应该是相同的。请参考这篇文章:https://medium.com/@martatatiana/poor-detective-angular2-browser-crash-and-debugelement-f0a651dbf33

感谢Rom的建议,大约一周前我刚看到了这篇文章。但是不能正确使用DebugElement很烦人,我认为这个功能相当不错。我会尝试您的解决方案,看看它是否能带来更好的结果。 - Shireilia

3

使用expect(debugElement).toBeTruthy();代替expect(debugElement).not.toBeNull(),因为当某些内容未定义时,not.toBeNull()可能不会按预期行事。如果您的debugElement未定义,则可能会出现问题。


但是你知道如果定义了debugElement,它如何崩溃吗?因为我至少希望如果debugElement中的元素损坏,会有一个错误日志或其他提示,而不是浏览器崩溃。 - Shireilia
经过更多的测试,真值/假值从未出现过这个问题。 - Shireilia
但我仍然不确定这如何导致整个测试套件崩溃。 - Shireilia

2

使用expect( Boolean(debugElement) ).toBeTruthy()代替

  • expect(debugElement).not.toBeNull()
  • 或者expect(debugElement).toBeTruthy()

这是一种解决方法,但对我来说感觉有点hacky。自从那篇文章发布以来,我在测试中所做的就是不直接在debug元素上进行测试,而是在子属性(如debugElement.nativeElement)上进行测试,这样所有的问题都解决了 :) - Shireilia

0

已经在https://dev59.com/VZ3ha4cB1Zd3GeqPXqm5#43756120的回答中涵盖了链接和内容。 - Stephen Kennedy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接