How to use Jasmine in Angular tests

Jasmine is Angular’s default testing framework, providing a behavior-driven development syntax for writing clean, readable tests. As the creator of CoreUI with over 12 years of Angular experience since 2014, I’ve used Jasmine extensively for testing thousands of components and services. Jasmine offers describe blocks for test suites, it blocks for individual tests, and powerful matchers for assertions. The framework includes spies for mocking functions and tracking calls without external dependencies.

Use Jasmine’s describe, it, and expect syntax to write organized, readable Angular tests.

import { ComponentFixture, TestBed } from '@angular/core/testing'
import { CalculatorComponent } from './calculator.component'

describe('CalculatorComponent', () => {
  let component: CalculatorComponent
  let fixture: ComponentFixture<CalculatorComponent>

  // Runs before each test
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [CalculatorComponent]
    }).compileComponents()

    fixture = TestBed.createComponent(CalculatorComponent)
    component = fixture.componentInstance
  })

  // Runs after each test
  afterEach(() => {
    fixture.destroy()
  })

  // Basic test
  it('should create', () => {
    expect(component).toBeTruthy()
  })

  // Test with matchers
  it('should add two numbers', () => {
    expect(component.add(2, 3)).toBe(5)
    expect(component.add(2, 3)).toEqual(5)
    expect(component.add(-1, 1)).toBe(0)
  })

  // Test with toBeTruthy/toBeFalsy
  it('should validate positive numbers', () => {
    expect(component.isPositive(5)).toBeTruthy()
    expect(component.isPositive(-5)).toBeFalsy()
    expect(component.isPositive(0)).toBeFalsy()
  })

  // Test with toContain
  it('should contain item in array', () => {
    const numbers = [1, 2, 3, 4, 5]
    expect(numbers).toContain(3)
    expect(numbers.length).toBe(5)
  })

  // Test with spies
  it('should call method when button clicked', () => {
    spyOn(component, 'calculate')
    component.onButtonClick()
    expect(component.calculate).toHaveBeenCalled()
    expect(component.calculate).toHaveBeenCalledTimes(1)
  })

  // Spy with return value
  it('should use spy return value', () => {
    spyOn(component, 'getValue').and.returnValue(42)
    expect(component.getValue()).toBe(42)
  })

  // Spy on property
  it('should track property access', () => {
    const spy = spyOnProperty(component, 'total', 'get').and.returnValue(100)
    expect(component.total).toBe(100)
    expect(spy).toHaveBeenCalled()
  })

  // Test exceptions
  it('should throw error for division by zero', () => {
    expect(() => component.divide(10, 0)).toThrow()
    expect(() => component.divide(10, 0)).toThrowError('Division by zero')
  })

  // Async test
  it('should fetch data asynchronously', async () => {
    const data = await component.fetchData()
    expect(data).toBeDefined()
    expect(data.length).toBeGreaterThan(0)
  })

  // Focused test (only this runs)
  fit('should run only this test', () => {
    expect(true).toBe(true)
  })

  // Skipped test
  xit('should skip this test', () => {
    expect(false).toBe(true)
  })
})

Common Jasmine matchers:

expect(value).toBe(expected)           // ===
expect(value).toEqual(expected)        // deep equality
expect(value).toBeTruthy()             // truthy
expect(value).toBeFalsy()              // falsy
expect(value).toBeNull()               // null
expect(value).toBeUndefined()          // undefined
expect(value).toBeDefined()            // not undefined
expect(array).toContain(item)          // array contains
expect(string).toMatch(/pattern/)      // regex match
expect(value).toBeGreaterThan(n)       // >
expect(value).toBeLessThan(n)          // <
expect(fn).toThrow()                   // throws error
expect(spy).toHaveBeenCalled()         // spy called
expect(spy).toHaveBeenCalledWith(args) // spy called with args

Best Practice Note

Use describe blocks to group related tests logically. Use beforeEach for setup common to all tests and afterEach for cleanup. Use fit to focus on a single test during development, but never commit focused tests. Use spies instead of actual method calls to isolate what you’re testing. Jasmine runs with Karma test runner by default in Angular CLI projects. This is the testing foundation we use in CoreUI for Angular—Jasmine’s clear syntax and powerful matchers for comprehensive test coverage.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to Add a Tab in HTML
How to Add a Tab in HTML

How to Center a Button in CSS
How to Center a Button in CSS

How to limit items in a .map loop in JavaScript
How to limit items in a .map loop in JavaScript

What is CoreUI and Why Should You Use It for Your Next Admin Dashboard?
What is CoreUI and Why Should You Use It for Your Next Admin Dashboard?

Answers by CoreUI Core Team