James B
James B

Reputation: 9605

Promise Fails to Resolve with TypeMoq Mock

I've defined MyService as follows

export interface MyService {
    doStuff(): Promise<any>;
}

and MyClass that consumes MyService as

import {MyService} from "./my.service";
import {Observable} from "rxjs/Observable";
export class MyClass {

    constructor(private myService: MyService) {}

    useMyService(): Observable<boolean> {
        return Observable.create(obs => {
            this.myService.doStuff()
                .then((res: any) => {
                    console.log("Promise resolved!");
                    obs.next(true);
                })
                .catch((err: any) => {
                    console.log("Promise rejected!");
                    obs.error(false);
                })
        });
    };    
}

In addition, I have an interface MyModel defined as

export interface MyModel {
    someProperty: string;
}

Now I want to write a test such that I can mock MyService using TypeMoq. So I did the following

describe('MyClass', () => {

    it('useMyService returns true when myService returns true', (done) => {
        let mockModel = TypeMoq.Mock.ofType<MyModel>();
        mockModel.setup(x => x.someProperty).returns(() => "info");    

        let mockMyService = TypeMoq.Mock.ofType<MyService>();
        mockMyService.setup(x => x.doStuff()).returns(() => Promise.resolve(mockModel.object));

        let myClass = new MyClass(mockMyService.object);

        myClass.useMyService().subscribe(
            (result: boolean) => {
                expect(result).toBeTruthy();
                done();
            },
            (error: any) => {
                expect(error).toBeFalsy();
                done();
            });
    });
});

However, the Promise.resolve(mockModel.object) never seems to resolve when supplied with the TypeMoq mock as shown above, i.e., I don't get "Promise resolved!" (or "Promise rejected!") printed to the console and the jasmine test times out.

If I replace Promise.resolve(mockModel.object) with Promise.resolve({ someProperty: 'info'}), i.e.,

let mockMyService = TypeMoq.Mock.ofType<MyService>();
        mockMyService.setup(x => x.doStuff()).returns(() => Promise.resolve({ someProperty: 'info'}));

then the test works (I get "Promise resolved!" printed to the console). Why doesn't Promise.resolve() resolve when supplied with a TypeMoq mock?

Upvotes: 4

Views: 2103

Answers (1)

Ron MacNeil
Ron MacNeil

Reputation: 640

According to the author, this is "a limitation of the underlying technology" and apparently not something they intend to correct for in TypeMoq.

A workaround is offered that involves setting up then() method stubs on mocks that promises resolve to:

mockModel.setup((x: any) => x.then).returns(() => undefined);

Whether this qualifies as a solution to the problem would seem to be a matter of opinion.

Upvotes: 5

Related Questions