Check out our Angular Book Series.

My Unit Tests are Running out of Order with Angular 8!

This is a weird one. I'm updating Unit Test from my LearnWith series for Angular 8. And I ran into a few tests that would inconsistently pass.

The app behind the LearnWith series is a task manager, and one of the tests that was failing was to mark a task completed.

Let's look at the test:


describe('completeTask() ', function () {
let task : TaskVO = {taskCategoryID:1,taskID:10,completed:true} as TaskVO;
};

This is a describe() block, for the completeTask() method and it also creates a default task.

I had two tests in this block. The first makes sure the task was completed:


it('Make task Completed', () =>
{
taskService.completeTask(task).subscribe(
value => {
expect(value.resultObject[0].completed).toBeTruthy();
});
const req = httpMock.expectOne(url) ;
req.flush({"resultObject":[task],"error":0});
}

I truncted it for simplicity. But, it takes the full task--defined as a constant in the describe block--passes that task into a service, creates a request, resolves it, and checks the value returned.

The same test suite had a test to mark a task not completE:


it('Make task Not Completed', () =>
{
task.completed = false;
taskService.completeTask(task).subscribe(
value => {
expect(value.resultObject[0].completed).toBeFalsy();
});
const req = httpMock.expectOne(url) ;
req.flush({"resultObject":[task],"error":0});
}

The second test sets the completed value on the task object to false; then runs very much the same code, and after the service is resolved; makes sure that the completed value is false.

The second test always ran without problems, but the first test would sporadically fail. My only explanation for this is that the tests must not be run in the same order on every execution of the test suite.

The task object is not reinitialized after every it() test, therefore the values can stay constant across multiple tests.

There are two solutions to this. The first is to make sure the first test sets the default value:


it('Make task Completed', () =>
{
task.completed = true;
// rest of test

That magically worked it.

The second solution is to move the task initialization into a beforeEach() block so it would be re-initialized before each test. That would look like this:


let task : TaskVO;

beforeEach(() =>
{
task = {taskCategoryID:1,taskID:10,completed:true} as TaskVO;
});

Either solution would solve the problem; and throughout my various tests I used one or the others depending upon what was failing.

Honestly, I'm surprised that this was not happening in versions of Angular prior to 8, so it took me a bit off guard.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.