Mocking Inputs in Angular Unit Tests

January 18, 2019

karma, a javascript testing framework

One nice part of Angular being an opinionated framework is that a component unit testing structure is provided right out of the box. When the cli is used to create a new component via ng g c [my-component] or a service via ng g s [my-service], a spec.ts file is automatically created that will run via ng test.

Jasmine is the testing framework used by angular for unit tests, while karma is the task runner that executes the tests.

Here’s an example of a test that would be generated for your main app component:

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';

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

    // dependency injection is handled here - any services that need to be stubbed out can be given in a 
    // 'providers' array and modules can be included via 'imports'.

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
    });
    TestBed.compileComponents();
  });

// this handles the actual component creation. notice that 'app' is the variable that
// refers to our component object

  it('should create the app', async(() => {
     fixture = TestBed.createComponent(AppComponent);
     app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));

// additional assertions can then be added to test different component features.
  it(`should have as title 'app works!'`, async(() => {
     fixture = TestBed.createComponent(AppComponent);
     app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('app works!');
  }));


});

Angular unit tests are simple to work with, but what about when your components need input properties via @Input() in their ts files? Without required inputs a component unit test will fail. Fortunately it’s incredibly easy to stub out inputs on a component. Let’s say we’re writing a unit test for a component called ‘MyComponent’ with inputs ‘name: string’ and ‘verticalLeap: number’:

import { TestBed, async } from '@angular/core/testing';
import { MyComponent } from './my.component';

describe('MyComponent', () => {

let component: MyComponent;
let fixture: ComponentFixture<MyComponent>

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        MyComponent
      ],
    });
    TestBed.compileComponents();
  });

  it('should create my component', async(() => {
     fixture = TestBed.createComponent(AppComponent);
     component = fixture.componentInstance;

     // provide inputs here
     component.name = 'John';
     component.verticalLeap = '32';

    expect(app).toBeTruthy();
  }));

That’s it! Remember, even though we’re dealing with frameworks it’s still JavaScript, and all we’re really doing is defining a property on an object. Now you can test components with input properties.


John D Potts

John D Potts

Web developer and speaker in Charlotte, NC.