In my test I'm importing a JSON file to set a mock value (which would usually be passed in to my component as an @Input()
).
It was my impression that Angular tests would reset component variables before each test runs if beforeEach
is used; therefore, changing the value of a component variable inside one test shouldn't affect other tests in the same testbed.
However, I'm finding that when a variable value is changed in a test it isn't being reset by the beforeEach
before the next test runs.
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'
});
...
How can I ensure that component variables are always reset back to the original before each test runs?
EDIT
I managed to replicate the bug in StackBlitz here.
In the second test, setting the value in this way:
component.board.type = 'Progress';
causes the next test to fail, whereas rewriting the whole object like this:
component.board = { id: 1, type: 'Progress' };
causes the next test to pass.
Any ideas?!
From your StackBlitz (and many log statements!) it appears that when you change the value in
component.board
it was also changing the value indata
. This makes sense as the assignment in thebeforeEach
method (component.board = data;
) would just be assigningcomponent.board
the same pointer asdata
. Then changing one would change the other.To get past this you should, as some of the comments mention, clone the
data
object rather than directly assigning it. You can do this usingJSON.parse(JSON.stringify(MockBoard['board']))
as Jelle mentioned or use something like Lodash'sclone
method (cloneDeep
for more complex objects).Here is an updated StackBlitz that you can use to compare to your original code.