In the previous article, we discussed Jasmine Tests, Jasmine is more customizable and provides a huge set of functionality. In this article, let's discuss the below important topics on Jasmine:
- Negative assertions in Jasmine Test
- Custom assertions in Jasmine Test
How to write Negative Assertions in Jasmine Test?
Jasmine provides negative test assertions as well, it is similar to assertions in jasmine, but it negates the actual assertion.
Any matcher can evaluate to negative assertions by chaining the expect call to not before matcher.
describe('Negative Expectaion Demo', () => {
it('Negative Expectaion Example', () => {
let a = 10;
let b = 20;
expect(a).not.toBe(b); //not is chained to expect
});
});
In the above example, not is chained to expect in the line expect(a).not.toBe(b);, Now test passes only if values of a and b are different otherwise test fails.
How to implement Custom Assertions in Jasmine Test?
Jasmine has a rich set of matchers included, however, it's common sometimes there will be a need for custom matchers. Some of the example includes verify the valid age, verify bank account number validity. In these cases, jasmine provides the functionality to write to custom assertions. As the name implies one can define the custom assertion statement.
In order to define jasmine assertions in typescript, there are three steps
- Step 1: Define the interface
- Step 2: Implement custom assertion
- Step 3: Add custom matcher to Jasmine and use in spec.
Step 1: Define the interface
Define an interface which will have all the required matcher as the function declaration. In [typescript],(https://www.toolsqa.com/protractor/typescript/) this is also called a definition file. A declaration should also include arguments of the function and return type.
Let's create matcher which validates age, save it in a file age.matcher.d.ts
//age.matcher.d.ts
declare namespace jasmine {
interface Matchers<T> {
toBeValidAge(expectationFailOutput?: any): boolean; //Custom matcher
}
}
Note: "?" is used to define the optional arguments in typescript function.
In the above example toBeValidAge() is custom matcher which accepts expectationFailOutput arguments optionally and returns boolean.
Step 2: Implement custom assertion
In the previous step, custom matcher is defined, This step is to implement actual custom assertions. The custom assertion function body must include pass and fail criteria.
Let's implement the custom matcher, save it in a file age.matcher.ts
//age.matcher.ts
import MatchersUtil = jasmine.MatchersUtil;
import CustomMatcherFactories = jasmine.CustomMatcherFactories;
import CustomEqualityTester = jasmine.CustomEqualityTester;
import CustomMatcher = jasmine.CustomMatcher;
import CustomMatcherResult = jasmine.CustomMatcherResult;
export const AgeVerifier: CustomMatcherFactories = {
toBeValidAge: function (util: MatchersUtil, customEqualityTester: CustomEqualityTester[]): CustomMatcher { //Custom assertion name
return {
compare: function (actual: any): CustomMatcherResult {
if(actual >= 18 ) { //Pass and fail criteria
return {
pass: true,
message: 'Valid age'
}
} else {
return {
pass: false,
message: 'Not a valid age'
}
}
}
}
}
};
Note: Interface file name and Implementation file name must be different.
Above example verifies the age group, person's age must 18 or above. Any age which falls below 18 is treated as Invalid age.
Step 3: Add custom assertions to Jasmine
Once Jasmine custom assertions are created, the next step is to add that to Jasmine. In other words, its the way jasmine can understand where custom matches are defined and it's implementation.
//test-spec.ts
////// <reference path="./age.matcher.d.ts" /> //Important! add reference to interfacc
import{AgeVerifier} from "./age.matcher" /Important! import the custom assertions
describe('Jasmine custom assertions example', () => {
beforeAll(()=>{
jasmine.addMatchers(AgeVerifier); //Important! add custom matcher to jasmine library
});
it('Jasmine custom assertions spec',()=>{
let myAge=15;
expect(myAge).toBeValidAge();
})
})
Explanation of the Code:
- ////// <reference path="./age.matcher.d.ts" /> : Refrence to the interface is added, this helps typescript to locate the custom assertion declaration.
- import{AgeVerifier} from "./age.matcher" : Import the custom matcher to spec, this helps to use the custom matcher inside spec.
- jasmine.addMatchers(AgeVerifier); : Add custom matcher to jasmine library so that jasmine can understand custom assertion.
After execution of test-spec.ts there should be failed output as age 15 doesn't belong to the valid age group.
As shown in the above example you can define as many as custom matchers in Jasmine, use it your spec.