Search code examples
angularprotractorcucumberangular-services

CucumberJS, Protractor, and Angular 5 mock out services


I am trying to make some cucumber test cases using protractor with my angular 5 application. I am not sure how to mock my services. I want my components to use my mock service whenever they call functions from them.

Here's a simple example:

foobar.component.ts

import { Component, OnInit } from '@angular/core';
import { TestService } from '../../../services/test.service';

@Component({
    selector: 'app-test',
    templateUrl: './test.component.html',
    styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
    myDataObject: any;

    constructor(private testService: TestService) {
        this.myDataObject = this.testService.getTestObject();
    }

    ngOnInit() {}
}

test.service.ts

import { Injectable } from '@angular/core';

@Injectable()
export class TestService {
    constructor() {}

    getTestObject(): any {
        return {
            'foo': 1,
            'bar': 2
        }
    }
}

foobar.step.ts

import { browser, element, by } from 'protractor';
const { Before, Given, When, Then, defineSupportCode } = require('cucumber');
const chai = require('chai').use(require('chai-as-promised'));
const expect = chai.expect;

defineSupportCode(function ({ setDefaultTimeout }) {
    setDefaultTimeout(120 * 1000);
});

Before(() => {
    // Setup a mock service and use the values I set here. In this case I would want to mock out whatever TestService.getTestObject() returns and have my component use the mock values.
}

Given('some test here', (next) => {
    next();
});

When('the page loads', (next) => {
    browser.get('/').then(function () {
        next();
    });
});

Then('some text here', (next) => {
    // Use mock values and create expect statement to see if something was shown on the page.
});

The reason I want to do this is because my templates depend on the values from the objects my services return to determine if some div blocks should be shown or not.

How can I mock my service and have my component use it in my protractor tests? Any help would be appreciated. Thank you!


Solution

  • As said in the comments you don't use TestBed for mocking Services in E2E-tests, but you can switch the environments when running tests, thus providing complete mock services:

    @NgModule({
      imports: [...],
      providers: [
        {
          provide: AbstractService,
          useClass: (environment.mockService ? TestService : RealService) // both extend AbstractService
        }
      ],
      declarations: ...,
      exports: ...
    })
    export class MyModule {}
    

    and in package.json (you need to set the environment with an own file and wire it up in the angular-cli.json as well)...

    "test": "ng test --env=unit-test",