在测试中,我正在导入JSON文件以设置模拟值(通常将其作为@Input()
传递到我的组件中)。
给我的印象是,如果使用beforeEach
,则Angular测试会在每次测试运行之前重置组件变量。因此,在一个测试中更改组件变量的值不应影响同一测试床中的其他测试。
但是,我发现在测试中更改变量值时,beforeEach
不会在下一次测试运行之前将其重置。
mock_board.json
{
"board": {
"type": "Archived"
}
}
component.spec.ts
import * as MockBoard from '../mock_board.json';
...
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture(MyComponent);
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
...
],
declarations: [
MyComponent
],
providers: [
...
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
component.board = MockBoard['board'];
fixture.detectChanges();
});
it('should display title if board type is `Progress`', () => {
component.board.type = 'Progress';
... // expectation here
});
it('should change the UI if board data changes', () => {
console.log(component.board.type); // expected 'Archived' but returns 'Progress'
});
...
如何确保每次运行测试之前始终将组件变量重置为原始变量?
编辑
我设法在StackBlitz here中复制了该错误。
在第二个测试中,以这种方式设置值:
component.board.type = 'Progress';
导致下一个测试失败,而像这样重写整个对象:
component.board = { id: 1, type: 'Progress' };
使下一个测试通过。
有什么想法吗?!
答案 0 :(得分:1)
从您的StackBlitz(和许多日志语句!)看来,当您更改component.board
中的值时,它也在更改data
中的值。这是有道理的,因为beforeEach
方法(component.board = data;
)中的分配将只分配component.board
与data
相同的指针。然后更改一个将更改另一个。
要克服这一点,您应该像某些注释中提到的那样,克隆data
对象,而不是直接分配它。您可以使用JSON.parse(JSON.stringify(MockBoard['board']))
(如 Jelle 所述),也可以使用类似Lodash的clone
方法(对于更复杂的对象,则使用cloneDeep
)。
Here is an updated StackBlitz,可用于与原始代码进行比较。