【发布时间】:2021-08-18 20:02:44
【问题描述】:
在我们的 Angular 项目中,我们正在将 jasmine 测试迁移到 jest。 当我们尝试在测试中模拟组件的 @Input 值时,我们遇到了一些问题。 例如,在 jamsine 中,我们习惯于这样写:
@Component({
selector: 'app-message[message]',
templateUrl: './message.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MessageComponent implements OnInit {
@Input() message!: Message;
}
describe('MessageComponent', () => {
let component: MessageComponent ;
let fixture: ComponentFixture<MessageComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [// some imports],
declarations: [MessageComponent]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MessageComponent);
component = fixture.componentInstance;
});
it('test1 with input message') {
component.message = new Message('xxx');
fixture.detectChanges();
// some expectations
}
it('test2 with another input message') {
component.message = new Message('yyy');
fixture.detectChanges();
// some expectations
}
});
使用 jasmine,这些测试总是通过,并且 Message 的实例总是在测试中这样设置。但是开玩笑的是,每次调用 fixture.detectChanges() 时,都会重置组件,并且所有 @Input 值都设置为未定义,我不知道如何处理它。 然后我尝试另一种方式来做这件事,灵感来自(Angular Unit-Test) How to mock input property in Jasmin?,我现在使用 HostComponent 来调用我的模板,比如
let testMessage: Message = generateMessage();
@Component({
selector: 'app-testhost',
template: `<app-message [message]="message"></app-message>`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FakeHostComponent {
message = testMessage;
}
如果我只有 1 个测试,它可以正常工作,但我不知道如何在每个测试中动态更改“消息”的值。我觉得我错过了什么或做错了什么。我应该为我的每个测试创建一个 FakeHostComponent 吗?
所以我需要帮助来使这些测试更漂亮和更有活力。另外我想了解为什么 fixture.detectChanges() 重置我的组件输入值
作为一种解决方法,我将 message 的值放在全局变量“testMessage”中并创建在每个测试中调用的这个方法,但我确信有一种方法可以更正确地做到这一点
const createComponent = (message: Message) => {
testMessage = message;
fixture = TestBed.createComponent(FakeHostComponent);
component = fixture.debugElement.children[0].componentInstance;
};
【问题讨论】: