在编写单元测试时,我遇到了一个奇怪的案例,我不知道问题出在哪里。
我已经准备了用于复制的短代码:
TestInjectable-简单的可注入类
@Injectable()
class TestInjectable {
testProperty = 'testValue';
}
TestComponent-使用TestInjectable
的小组件@Component({
providers: [TestInjectable],
template: ''
})
class TestComponent {
constructor(private injectable: TestInjectable) {
}
doTest() {
return this.injectable.testProperty;
}
}
单元测试
describe('Test TestComponent', () => {
beforeEach(async(() => {
let testInjectableMock: TestInjectable = new TestInjectable();
testInjectableMock.testProperty = 'valueInMock';
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, useValue: testInjectableMock}],
declarations: [TestComponent]
}).compileComponents();
}));
it('should do something', () => {
let fixture: ComponentFixture<TestComponent> = TestBed.createComponent(TestComponent);
let component: TestComponent = fixture.componentInstance;
expect(component.doTest()).toBe('valueInMock');
});
});
由于我将testInjectableMock
设置为valueInMock
,因此我希望该组件将返回该值。问题在于组件返回的是默认值testValue
,测试失败并显示以下信息:
预计“ testValue”为“ valueInMock”。
即使我使用TestBed
属性提供实例,听起来TestInjectable
仍在创建useValue
的另一个实例。
providers: [{provide: TestInjectable, useValue: testInjectableMock}]
有人知道我是否错过了某件事,或者是抓住了什么,以及如何说服TestBed
使用模拟实例吗?
答案 0 :(得分:0)
尝试
describe('Test TestComponent', () => {
let testInjectableMock: TestInjectable = new TestInjectable();
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, useValue: testInjectableMock}],
declarations: [TestComponent]
}).compileComponents();
}));
it('should do something', () => {
let fixture: ComponentFixture<TestComponent> = TestBed.createComponent(TestComponent);
let component: TestComponent = fixture.componentInstance;
testInjectableMock.testProperty = 'valueInMock';
expect(component.doTest()).toBe('valueInMock');
});
});
答案 1 :(得分:0)
我怀疑即使使用useValue,您也不会获得testInjectableMock的不变版本。
尝试一下?
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, useValue: new TestInjectable()}],
declarations: [TestComponent]
}).compileComponents().then(() => {
const testInjectableMock = TestBed.get(TestInjectable);
testInjectableMock.setTestProperty('valueInMock');
});
}));
答案 2 :(得分:0)
Angular DI会克隆useValue
提供的对象,并且从其外观来看,这样做是否正确:
https://github.com/angular/angular/issues/10788
您应该改用Factory:
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, /*-->*/ useFactory: () => testInjectableMock}],
declarations: [TestComponent]
}).compileComponents();