【问题标题】:Angular unit testing component ngIf element is nullAngular 单元测试组件 ngIf 元素为 null
【发布时间】:2021-04-13 16:11:06
【问题描述】:

我有一个包含一些 *ngIf 语句的组件,其中大部分如下所示

<ul *ngFor="let item of items">
<li> 
    <ng-container *ngIf="itemCount && item.GroupId == 4">
        <span class="bridge">{{itemCount}}</span>
    </ng-container>
</li>
... and so on

在我的规范文件中,我有一个测试试图检查 itemCount 不为空/空且 groupId = 4...然后检查跨度是否包含正确的项目计数。

我已经花了几个小时来解决这个问题,但无论我尝试什么尝试访问 span,都会导致 null 并且测试失败。

下面是其中一项测试的示例

if('should show the correct item count', () =>{
    let component = fixture.componentInstance;
    component.itemCount = 4;
    fixture.detectChanges();

    let bridge = fixture.debugElement.query(By.css('.bridge'));
    expect(bridge).tobeTruthy();
});


正如我上面所说,经过多次尝试,无论如何这总是无效的。我已经调试了测试并确认正在使用正确的 groupId 还确认 itemCount 不为空或不为空,因此 *ngIf 的两个条件都应该满足 - 但跨度不存在所以我必须假设有有什么不对劲。

请原谅拼写错误,我正在手动复制代码,但它当前确实运行,只是没有成功。

任何指针?

更新

这里有更多信息,组件填充了虚拟数据的 beforeEach。

const ItemServiceStub = jasmine.createSpyObj('ItemService', ['getItems']);

beforeEach(() =>{
    TestBed.configureTestingModule({
        declarations: [ItemComponent],
        providers: [{provide: ItemService, useValue: ItemServiceStub}]
    }).compileComponents();
});

beforeEach(() => {
    itemService = Testbed.inject(ItemService);

    spyOn(itemService, 'getItems').and.callFake(() => of(fakeItems));

    fixture = TestBed.createComponent(ItemComponent);
    fixture.autoDetectChanges();
});

更新 2 这是正在设置的假数据

describe('item tests', () => {

let fakeItems: Item[];

fakeItems = [
   {GroupId: '2', ItemName: 'test', isExternal: false},
   {GroupId: '3', ItemName: 'testing', isExternal: false},
   {GroupId: '4', ItemName: 'test item', isExternal: false}
];

});


【问题讨论】:

  • 测试中component.items的值是多少?
  • 我会用这个细节更新问题...
  • @Andrei - 我添加了更多细节,但为了回答您的问题,测试中 component.items 的值对应于我提供的假数据。我正在调试,可以看到数据在那里,可以看到 itemCount 是我设置的(设置为 4)。
  • 是假数据 - 正确的对象,其中任何一个具有 GroupId == 4?
  • @Andrei 是的,GroupId == 4 的项目在那里,并且正在设置项目计数。我从调试中得到了所有这些,但也许调试不是检查这些东西的好地方?老实说,单元测试 Angular 让我很生气,即使是最基本的东西也很难测试。

标签: angular unit-testing jasmine


【解决方案1】:

试试这个:

it('should show the correct item count', () =>{
    let component = fixture.componentInstance;
    component.items = [...fakeItems];
    component.itemCount = 4;
    fixture.detectChanges();

    let bridge = fixture.debugElement.query(By.css('.bridge'));
    console.log(bridge); // make sure it logs something to the console
    expect(bridge).toBeTruthy();
});

如果这不起作用,我认为ul 顶部有一个*ngIf,它不是真的,因此不会显示这个ul

要对此进行测试,请尝试:

<ul class="dummy-class" *ngFor="let item of items">
<li> 
    <ng-container *ngIf="itemCount && item.GroupId == 4">
        <span class="bridge">{{itemCount}}</span>
    </ng-container>
</li>
it('should show the correct item count', () =>{
    let component = fixture.componentInstance;
    component.items = [...fakeItems];
    component.itemCount = 4;
    fixture.detectChanges();

    let bridge = fixture.debugElement.query(By.css('ul.dummy-class'));
    console.log(ul); // make sure it logs something to the console
    expect(ul).toBeTruthy();
});

【讨论】:

  • 谢谢,我试试看。
  • 所以第一个建议在控制台中给我 null,第二个按预期输出 UL。
  • 这很奇怪,我会想象第一个测试会起作用。
  • 其实我错了....成功了!谢谢!在这上面花费了几个小时。上帝。
猜你喜欢
  • 2020-11-12
  • 2019-09-21
  • 1970-01-01
  • 2018-09-10
  • 2021-01-05
  • 1970-01-01
  • 2017-10-10
  • 2020-03-06
  • 1970-01-01
相关资源
最近更新 更多