Jasmine Testing Framework
Learn Jasmine testing framework for Angular with describe, it, expect, matchers, spies, hooks, async testing, mocking, best practices, and enterprise interview questions.
Jasmine is the default Behavior-Driven Development (BDD) testing framework used by Angular for writing unit tests.
It provides an expressive syntax that makes tests easy to read, write, and maintain.
Jasmine allows developers to:
- Test components
- Test services
- Test pipes
- Test directives
- Mock dependencies
- Verify function calls
- Test asynchronous code
This guide covers everything you need to know about Jasmine for Angular interviews and enterprise development.
Table of Contents
- What is Jasmine?
- Why Use Jasmine?
- Jasmine Architecture
- Test Suites
- Test Cases
- Assertions
- Matchers
- Hooks
- Jasmine Spies
- Mocking
- Async Testing
- Enterprise Banking Example
- Best Practices
- Common Mistakes
- Top 10 Interview Questions
- Interview Cheat Sheet
- Summary
What is Jasmine?
Jasmine is a Behavior-Driven Development (BDD) testing framework for JavaScript and TypeScript.
It works well with Angular because it:
- Has simple syntax
- Supports mocking
- Supports asynchronous testing
- Integrates with Karma
- Requires minimal configuration
Why Use Jasmine?
Benefits include:
- Easy to read
- Easy to write
- Fast execution
- Supports spies
- Rich assertion library
- Framework independent
- Excellent Angular integration
Jasmine Architecture
flowchart LR
TestSuite
TestSuite --> TestCase
TestCase --> Expectation
Expectation --> Matcher
Matcher --> Result
Test Suite
A test suite groups related test cases.
describe('Calculator', () => {
});
The describe() function defines a suite.
Test Case
Each it() block represents one test case.
describe('Calculator', () => {
it('should add numbers', () => {
expect(2 + 3).toBe(5);
});
});
One it() should verify one behavior.
Jasmine Test Flow
flowchart LR
describe
describe --> beforeEach
beforeEach --> it
it --> expect
expect --> Matcher
Matcher --> Result
Assertions
Assertions verify expected behavior.
expect(result).toBe(10);
General syntax
expect(actual)
.matcher(expected);
Common Matchers
toBe()
Checks strict equality.
expect(5).toBe(5);
toEqual()
Compares object values.
expect(customer)
.toEqual({
id:1,
name:'John'
});
toBeTruthy()
expect(isLoggedIn)
.toBeTruthy();
toBeFalsy()
expect(hasError)
.toBeFalsy();
toContain()
expect(skills)
.toContain("Angular");
toBeNull()
expect(value)
.toBeNull();
toBeUndefined()
expect(result)
.toBeUndefined();
Matcher Summary
| Matcher | Purpose |
|---|---|
| toBe() | Strict equality |
| toEqual() | Deep object comparison |
| toContain() | Collection contains value |
| toBeTruthy() | Truthy value |
| toBeFalsy() | Falsy value |
| toBeNull() | Null check |
| toBeUndefined() | Undefined check |
| toThrow() | Exception verification |
Hooks
Jasmine provides lifecycle hooks.
| Hook | Purpose |
|---|---|
| beforeEach() | Run before every test |
| afterEach() | Run after every test |
| beforeAll() | Run once before all tests |
| afterAll() | Run once after all tests |
Example
beforeEach(() => {
service = new MathService();
});
Hooks Lifecycle
flowchart TD
beforeAll
beforeAll --> beforeEach
beforeEach --> Test1
Test1 --> afterEach
afterEach --> beforeEach2
beforeEach2 --> Test2
Test2 --> afterEach2
afterEach2 --> afterAll
Jasmine Spies
Spies monitor function calls.
Example
const service = jasmine.createSpyObj(
'CustomerService',
['loadCustomers']
);
Mock return value
service.loadCustomers
.and.returnValue([]);
Verify call
expect(service.loadCustomers)
.toHaveBeenCalled();
Spy Methods
| Method | Purpose |
|---|---|
| createSpy() | Create spy |
| createSpyObj() | Create object spy |
| spyOn() | Spy existing method |
| and.returnValue() | Mock value |
| and.callFake() | Custom implementation |
| and.callThrough() | Call real method |
spyOn()
Monitor an existing method.
spyOn(service, 'saveCustomer')
.and.callThrough();
Verify
expect(service.saveCustomer)
.toHaveBeenCalled();
Mocking Dependencies
Mock instead of calling real services.
const authService = {
login: jasmine
.createSpy()
.and.returnValue(true)
};
Provider
providers: [
{
provide: AuthService,
useValue: authService
}
]
Async Testing
Jasmine supports asynchronous tests.
Example
it('loads customers',
async () => {
await service.load();
expect(service.data.length)
.toBeGreaterThan(0);
});
Angular also supports:
- fakeAsync()
- tick()
- waitForAsync()
Testing Exceptions
expect(() => {
throw new Error();
})
.toThrow();
Focused Tests
Run one suite.
fdescribe('Customer', () => {
});
Run one test.
fit('should load', () => {
});
⚠️ Remove fdescribe() and fit() before committing code.
Disabled Tests
Disable one suite.
xdescribe('Customer', () => {
});
Disable one test.
xit('should load', () => {
});
Useful during development, but avoid leaving disabled tests in long-term production branches.
Enterprise Banking Example
Application Modules
- Login
- Accounts
- Transactions
- Loans
- Credit Cards
- Investments
Testing Strategy
| Layer | Jasmine Tests |
|---|---|
| Services | Business Logic |
| Components | UI Behavior |
| Pipes | Formatting |
| Validators | Form Validation |
| Guards | Authentication |
| Interceptors | Security |
Enterprise Testing Flow
flowchart LR
Developer
Developer --> Jasmine
Jasmine --> Karma
Karma --> Browser
Browser --> TestReport
Performance Best Practices
| Practice | Benefit |
|---|---|
| One Behavior Per Test | Better readability |
| Mock Dependencies | Faster execution |
| Independent Tests | Reliable results |
| Avoid Shared State | Stable tests |
| Use Spies | Better verification |
| Test Edge Cases | Higher quality |
| Keep Tests Small | Easy maintenance |
| Run in CI/CD | Early bug detection |
Common Mistakes
Testing Too Much
❌ Bad
it('should test everything', () => {
});
Each test should verify a single behavior.
Forgetting to Reset Mocks
Reset spies or recreate mock objects between tests to avoid state leaking from one test to another.
Calling Real APIs
Always mock:
- HTTP requests
- Databases
- External services
Using fit() in Production
Leaving focused tests in source control causes other tests to be skipped.
Ignoring Error Scenarios
Test:
- Invalid input
- Null values
- Empty lists
- Exceptions
- Failed API responses
Jasmine Best Practices
| Practice | Recommendation |
|---|---|
| One Assertion Focus | Yes |
| Descriptive Test Names | Yes |
| Mock External Services | Always |
| Independent Tests | Yes |
| Test Edge Cases | Yes |
| Avoid Shared State | Yes |
| Use beforeEach() | Setup |
| Run in CI/CD | Yes |
Advantages
| Benefit | Description |
|---|---|
| Readable Syntax | Easy maintenance |
| BDD Style | Business-focused tests |
| Rich Matchers | Powerful assertions |
| Spies | Easy mocking |
| Angular Support | Native integration |
| Fast Execution | Quick feedback |
Top 10 Jasmine Interview Questions
1. What is Jasmine?
Answer
Jasmine is a Behavior-Driven Development (BDD) testing framework used for writing unit tests in Angular and JavaScript applications.
2. What is the purpose of describe()?
Answer
describe() defines a test suite that groups related test cases together.
3. What does it() do?
Answer
it() defines an individual test case that verifies one specific behavior.
4. What is expect()?
Answer
expect() creates an assertion that compares the actual result with the expected result using a matcher.
5. What are Jasmine Matchers?
Answer
Matchers are assertion methods such as:
- toBe()
- toEqual()
- toContain()
- toBeTruthy()
- toThrow()
that verify expected behavior.
6. What are Jasmine Spies?
Answer
Spies monitor function calls, replace implementations, mock return values, and verify interactions with dependencies.
7. What is beforeEach()?
Answer
beforeEach() runs before every test case and is typically used to initialize shared objects or configure the test environment.
8. What is the difference between toBe() and toEqual()?
Answer
toBe() performs strict identity/value comparison (===), while toEqual() performs deep comparison of object structures and values.
9. What are fit() and fdescribe()?
Answer
They execute only the focused test or test suite. They are useful during development but should not be committed because they skip other tests.
10. What are Jasmine testing best practices?
Answer
- Write one behavior per test
- Use descriptive test names
- Mock external dependencies
- Keep tests independent
- Test edge cases
- Avoid focused tests in committed code
- Automate tests in CI/CD
Interview Cheat Sheet
| Requirement | Jasmine Feature |
|---|---|
| Test Suite | describe() |
| Test Case | it() |
| Assertion | expect() |
| Equality | toBe() |
| Object Comparison | toEqual() |
| Mocking | Spy |
| Setup | beforeEach() |
| Cleanup | afterEach() |
| Async Testing | async / fakeAsync |
| Enterprise Testing | Jasmine + Karma |
Summary
Jasmine is the core testing framework used by Angular for writing clean, maintainable, and reliable unit tests. Its expressive BDD syntax, rich matcher library, lifecycle hooks, and powerful spying capabilities make it ideal for testing components, services, and business logic. Combined with Angular's TestBed and Karma, Jasmine enables teams to build high-quality, enterprise-ready applications with confidence.
Key Takeaways
- ✅ Jasmine is Angular's default BDD testing framework.
- ✅
describe()defines a test suite. - ✅
it()defines an individual test case. - ✅
expect()creates assertions. - ✅ Matchers verify expected behavior.
- ✅ Spies mock and verify method calls.
- ✅ Lifecycle hooks simplify setup and cleanup.
- ✅ Mock external dependencies for fast, reliable tests.
- ✅ Keep tests independent and focused.
- ✅ Jasmine is one of the most frequently asked Angular interview topics.
Next Article
➡️ 111-Karma-QA.md