Angular5 TestBed useValue 似乎没有注入相同的对象实例
Angular5 TestBed useValue seems not injecting same object instance
在编写单元测试时遇到奇怪的情况,我不明白问题出在哪里。
我已经准备好重现的短代码:
TestInjectable - 简单的注射剂 class
@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
我希望组件会 return 这个值。问题是组件 returning testValue
这是默认值,测试失败:
Expected 'testValue' to be 'valueInMock'.
听起来 TestBed
正在创建 TestInjectable
的另一个实例,即使我使用 useValue
属性.
提供了实例
providers: [{provide: TestInjectable, useValue: testInjectableMock}]
有谁知道我是否遗漏了什么或问题在哪里以及如何说服 TestBed
使用模拟实例?
尝试
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');
});
});
我怀疑即使使用 useValue,您也没有得到未受污染的 testInjectableMock 版本。
试试这个?
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, useValue: new TestInjectable()}],
declarations: [TestComponent]
}).compileComponents().then(() => {
const testInjectableMock = TestBed.get(TestInjectable);
testInjectableMock.setTestProperty('valueInMock');
});
}));
Angular DI 克隆了 useValue
提供的对象,从外观上看,是否错误:
https://github.com/angular/angular/issues/10788
您应该改用工厂:
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, /*-->*/ useFactory: () => testInjectableMock}],
declarations: [TestComponent]
}).compileComponents();
在编写单元测试时遇到奇怪的情况,我不明白问题出在哪里。
我已经准备好重现的短代码:
TestInjectable - 简单的注射剂 class
@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
我希望组件会 return 这个值。问题是组件 returning testValue
这是默认值,测试失败:
Expected 'testValue' to be 'valueInMock'.
听起来 TestBed
正在创建 TestInjectable
的另一个实例,即使我使用 useValue
属性.
providers: [{provide: TestInjectable, useValue: testInjectableMock}]
有谁知道我是否遗漏了什么或问题在哪里以及如何说服 TestBed
使用模拟实例?
尝试
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');
});
});
我怀疑即使使用 useValue,您也没有得到未受污染的 testInjectableMock 版本。
试试这个?
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, useValue: new TestInjectable()}],
declarations: [TestComponent]
}).compileComponents().then(() => {
const testInjectableMock = TestBed.get(TestInjectable);
testInjectableMock.setTestProperty('valueInMock');
});
}));
Angular DI 克隆了 useValue
提供的对象,从外观上看,是否错误:
https://github.com/angular/angular/issues/10788
您应该改用工厂:
TestBed.configureTestingModule({
providers: [{provide: TestInjectable, /*-->*/ useFactory: () => testInjectableMock}],
declarations: [TestComponent]
}).compileComponents();