Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using TypeMoq Mock With Angular TestBed

I've defined a FooService as follows

import {Injectable} from "@angular/core";
export interface Foo {
    Foo(): string;
}

@Injectable()
export class FooService implements Foo {
    Foo(): string {
        return "Fooey!";
    }
}

and a BarComponent like this

import {Component} from "@angular/core";
import {FooService} from "./foo.service";

@Component({
    moduleId: 'module.id',
    template: '<h1>Bar Component</h1>'
})
export class BarComponent {
    constructor(private fooService: FooService) {}

    doFoo(): string {
        return(this.fooService.Foo());
    }
}

Now I want to test my BarComponent and I'd like to use TypeMoq to mock the FooService, so I did the following

import * as TypeMoq from 'typemoq';
import {Foo, FooService} from "./foo.service";
import {TestBed, async} from "@angular/core/testing";
import {BarComponent} from "./bar.component";

describe('BarComponent', () => {
    let component: BarComponent;
    let mockFooService: TypeMoq.IMock<Foo>;

    beforeEach(async(() => {
        mockFooService = TypeMoq.Mock.ofType<Foo>();
        TestBed.configureTestingModule({
            declarations: [BarComponent],
            providers: [{ provide: FooService, useValue: mockFooService.object}]
        });
    }));

    beforeEach(() => {
        let fixture = TestBed.createComponent(BarComponent);
        component = fixture.componentInstance;
    });

    it('does something', () => {
        mockFooService.setup(x => x.Foo()).returns(() => "FooBar!");
        expect(component.doFoo()).toEqual("FooBar!");
    });

});

However running the above gives the following error

SyntaxError: Function arg string contains parenthesis
        at new Function (<anonymous>)
        at evalExpression (webpack:///~/@angular/compiler/@angular/compiler.es5.js:25431:25 <- config/karma-test-shim.js:59412:40)
        at jitStatements (webpack:///~/@angular/compiler/@angular/compiler.es5.js:25448:0 <- config/karma-test-shim.js:59429:12)
        at JitCompiler._compileModule (webpack:///~/@angular/compiler/@angular/compiler.es5.js:25658:0 <- config/karma-test-shim.js:59639:35)
        at createResult (webpack:///~/@angular/compiler/@angular/compiler.es5.js:25613:0 <- config/karma-test-shim.js:59594:106)
        at JitCompiler._compileModuleAndAllComponents (webpack:///~/@angular/compiler/@angular/compiler.es5.js:25616:0 <- config/karma-test-shim.js:59597:40)
        at JitCompiler.compileModuleAndAllComponentsSync (webpack:///~/@angular/compiler/@angular/compiler.es5.js:25559:0 <- config/karma-test-shim.js:59540:23)
        at TestingCompilerImpl.compileModuleAndAllComponentsSync (webpack:///~/@angular/compiler/@angular/compiler/testing.es5.js:475:0 <- config/karma-test-shim.js:68201:31)
        at TestBed._initIfNeeded (webpack:///~/@angular/core/@angular/core/testing.es5.js:705:0 <- config/karma-test-shim.js:21376:36)
        at TestBed.createComponent (webpack:///~/@angular/core/@angular/core/testing.es5.js:791:0 <- config/karma-test-shim.js:21462:14)
        at Function.TestBed.createComponent (webpack:///~/@angular/core/@angular/core/testing.es5.js:610:0 <- config/karma-test-shim.js:21281:29)
        at Object.<anonymous> (webpack:///src/app/auth/login/bar.component.spec.ts:19:30 <- config/karma-test-shim.js:99954:41)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:365:0 <- config/karma-test-shim.js:65763:26)
        at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- config/karma-test-shim.js:65294:39)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:364:0 <- config/karma-test-shim.js:65762:32)
        at Zone.run (webpack:///~/zone.js/dist/zone.js:125:0 <- config/karma-test-shim.js:65523:43)
        at Object.<anonymous> (webpack:///~/zone.js/dist/jasmine-patch.js:104:0 <- config/karma-test-shim.js:65010:34)
        at webpack:///~/@angular/core/@angular/core/testing.es5.js:96:0 <- config/karma-test-shim.js:20767:17
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:365:0 <- config/karma-test-shim.js:65763:26)
        at AsyncTestZoneSpec.onInvoke (webpack:///~/zone.js/dist/async-test.js:49:0 <- config/karma-test-shim.js:64605:39)
        at ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:76:0 <- config/karma-test-shim.js:65291:39)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:364:0 <- config/karma-test-shim.js:65762:32)
        at Zone.run (webpack:///~/zone.js/dist/zone.js:125:0 <- config/karma-test-shim.js:65523:43)
        at AsyncTestZoneSpec._finishCallback (webpack:///~/@angular/core/@angular/core/testing.es5.js:91:0 <- config/karma-test-shim.js:20762:25)
        at webpack:///~/zone.js/dist/async-test.js:38:0 <- config/karma-test-shim.js:64594:31
        at ZoneDelegate.invokeTask (webpack:///~/zone.js/dist/zone.js:398:0 <- config/karma-test-shim.js:65796:31)
        at Zone.runTask (webpack:///~/zone.js/dist/zone.js:165:0 <- config/karma-test-shim.js:65563:47)
        at ZoneTask.invoke (webpack:///~/zone.js/dist/zone.js:460:0 <- config/karma-test-shim.js:65858:38)
        at timer (webpack:///~/zone.js/dist/zone.js:1732:0 <- config/karma-test-shim.js:67130:29)

Is it possible to use TypeMoq's with the angular TestBed and if so how do you do it correctly?

like image 428
James B Avatar asked May 30 '17 21:05

James B


Video Answer


1 Answers

I was running into this also, it's coming in because of how you're doing your providers.

Change

providers: [{ provide: FooService, useValue: mockFooService.object}]

to

providers: [{ provide: FooService, useFactory: () => { return mockFooService.object } }]

Using the factory function to return got rid of errors for me. If you use useClass you'll get an error about param.map is not a function, and if you use useValue you get an error about unexpected parenthesis. useFactory and just an inline function that returns the moq.object works, though.

like image 162
Paul Avatar answered Oct 21 '22 03:10

Paul