I am learning how to Angular Test and something strange happens to me. Thing is, WITH THE SAME EXACT CODE, when I do ng test
sometimes the substract IT block is executed before the add IT block, when this one is supposed to be executed the first (and sometimes it actually does):
This is the spec code:
import { CalculatorService } from './calculator.service';
describe ('calculatorService',()=>{
let calculator:CalculatorService;
let loggerSpy:any;
beforeEach(()=>{
console.log ("calling the beforeEach");
loggerSpy=jasmine.createSpyObj('LoggerServiceSpy', ['log']);
calculator= new CalculatorService(loggerSpy);
});
it('should add two numbers', ()=>{
let result=calculator.add(2,2);
console.log ("add test");
expect(result).toBe(4);
expect(loggerSpy.log).toHaveBeenCalledTimes(1);
});
it('should substract two numbers', ()=>{
let result=calculator.subtract(2,2);
console.log ("substract test");
expect(result).toBe(0, "unexpected substracion result");
expect(loggerSpy.log).toHaveBeenCalledTimes(1);
});
});
And this what I obtain sometimes:
Other times I just kill terminal (integrated terminal in Visual Studio Code, it this helps you), execute ng test
again, and normal flow is done... What am I doing wrong?
EDIT: I add the calculator and logger services code in case it helps (also I don´t know why this.logger.log
test is not outputed when I do the ng test
but I guess that is another question
calculator-service.ts
import {Injectable} from '@angular/core';
import {LoggerService} from './logger.service';
@Injectable({
providedIn: 'root'
})
export class CalculatorService {
constructor(private logger: LoggerService) {
}
add(n1: number, n2:number) {
this.logger.log("Addition operation called");
return n1 n2;
}
subtract(n1: number, n2:number) {
this.logger.log("Subtraction operation called");
return n1 - n2;
}
}
logger-service.ts
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class LoggerService {
log(message:string) {
console.log(message);
}
}
CodePudding user response:
The reason for this is that Jasmine executes tests in a random order by default. This can be changed by setting random: false
in your karma.conf
file under the jasmine
property as shown here in the README.
This default behavior of running your unit tests randomly is actually a good thing, however. A general principle of writing good unit tests is to write them in such a way as they are fully self-contained -- meaning, each test has everything it needs to execute by itself. If your tests have to run in a specific order in order to pass, it generally means the tests depend on each other, and this is considered bad practice.
If you have to run your tests in a specific order for some reason though, you can certainly do so.