【发布时间】:2021-09-20 15:08:59
【问题描述】:
我正在使用 Jasmine 在 Angular 中对组件进行单元测试。 我的测试
it('contacts should be passed to child component', fakeAsync(() => {
const newContact: Contact = {
id: 1,
name: 'Jason Pipemaker'
};
const contactsList: Array<Contact> = [newContact];
contactsComponent.contacts = contactsList;//change on parent component
tick()
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(childComponents()[0].contacts).toEqual(contactsComponent.contacts);//want to check if changed on child also
})
}));
我想测试父母的变化是否会反映在孩子身上,就像在真实场景中发生的那样。
我已经测试了当一切开始时值是相等的,但是我想测试当一个人改变父值时的场景,这应该会自动反映在孩子身上。
it('contacts should be the same', () => {
expect(childComponents([0].contacts)
.toEqual(contactsComponent.contacts);
});
错误:
预期 $.length = 0 等于 1。 预期 $[0] = undefined 等于 Object({ id: 1, name: 'Jason Pipemaker' })。
我的解读:不等更新测试。
也许它甚至不是单元测试?既然要测试绑定,可能是集成测试吧。
目前的建议
建议 1:我会尝试 contactsComponent.contacts = JSON.parse(JSON.stringify(contactsList))
cmets:谢谢,它不起作用。看到我一开始就已经测试过了:一切都通过了。问题是。为什么它在开始/启动时起作用,但在启动后不起作用?我想这是一个在测试之前以某种方式确保一切都完成的问题:一个异步问题,而不是 JSON.stringify。我不知道如何用代码来做到这一点!简单来说:我正在更改父母的某些内容,并希望确保孩子收到更改,就像它发生在真实场景中一样。感谢您的参与! ????????? 我的 HTML:
<app-contact-list [contacts]=contacts></app-contact-list>
PS。 app-contact-list 是孩子:
export class ContactListComponent implements OnInit {
.......
@Input('contacts') contacts: Contact[];//the input for the component
建议 2:我认为您应该单独测试组件。
评论: 关于嘲笑孩子,我已经在用 ng-mock 嘲笑了
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ContactsComponent,
MockComponent(ContactListComponent)],
}).compileComponents();
}));
缺点:一些组织不允许安装这些软件包,因此,应该按照建议手动模拟。
建议 3:您可以通过利用 async/await 语法来避免它。
评论:试过了,但没用,和以前一样的问题。似乎代码在测试之前正在执行。我遇到了与 Jest 相同的问题,学到了一个以前从未发生过的技巧。我想我错过了类似的东西,确保测试在测试之前等待最终修改。
代码:一些人建议提供代码。 在这里:https://github.com/JorgeGuerraPires/testing-angular-applications/tree/master/website/src/app/contacts
也许有人可以按照建议制作 StackBlitz!????????????
最终解决方案
为了结束这个问题,我决定在一个简单的案例中进行测试,这样被测试的核心思想将是唯一的关注点。测试前查看完整的简单应用程序here。并查看最终测试文件here。
我从这两个答案中汲取了见解,并接受了对我帮助最大的一个,即使是 cmets 也有帮助。
谢谢大家!
【问题讨论】:
-
我会尝试使用
contactsComponent.contacts = JSON.parse(JSON.stringify(contactsList)) -
谢谢,它不起作用。看到我一开始就已经测试过了:一切都通过了。问题是。为什么它在开始/启动时起作用,但在启动后不起作用?我想这是一个在测试之前以某种方式确保一切都完成的问题:一个异步问题,而不是 JSON.stringify。我不知道如何用代码来做到这一点!感谢您的参与! ????????????
-
如果你能做一个简单的
Stackblitz将是完美的分析! -
我没有时间详细回答,但您可以使用
fixture.detectChanges()在 TestBed 中强制渲染。根据您的具体情况,您可能需要将其与fakeAsync块和tick()或async和whenStable()结合使用。也就是说,我对单元测试的偏好是尽可能地模拟依赖项。孩子应该可以独立于父母进行测试,反之亦然。对于测试全屏——而不是组件——我更喜欢 E2E 测试。 -
对于此类测试,角度具有angular.io/guide/… 技术。为什么你需要 tick 和 fakeAsync 呢?
标签: angular unit-testing tdd karma-jasmine