yktoo
yktoo

Reputation: 2986

Jasmine & Angular: Injecting a service into a service mock

We write a suite of unit tests for an Angular application with many services. It's convenient to provide fake service implementations, which generally do nothing, to be plugged into the app module, for example:

'use strict';

describe('ServiceUnderTest', function () {

    beforeEach(module('app', FakeServiceA, FakeServiceB));

    ...

}

// Fake service implementations (global functions):

function FakeServiceA($provide) {
    $provide.value(
        'ServiceA'
        { foo: function () {} }
    );
}

function FakeServiceB($provide) {
    $provide.value(
        'ServiceB'
        { bar: function () {} }
    );
}

Now, if I want them to actually do something instead of nothing, for instance, reject a promise, I hit the problem of injecting a dependency. What I want is:

function FakeServiceA($provide, $q) {
    $provide.value(
        'ServiceA'
        { foo: function () { return $q.reject('Nope!'); } }
    );
}

But it seems to be impossible to inject $q this way. Is there any other way how it can be achieved when registering a module?

Upvotes: 0

Views: 619

Answers (1)

Estus Flask
Estus Flask

Reputation: 223204

$q can't be injected this way

function FakeServiceA($provide, $q) { ...

because the specified dependencies are injected by provider injector, as described here (the fact that $provide can be used there makes a hint about that), while service instances ($q) have to be injected by instance injector. Obviously, it can't inject $q because it wasn't instantiated from $qProvider at this point.

It has to be something like that:

function FakeServiceA($provide) {
    $provide.factory('ServiceA', function ($q) {
        return { foo: function () { return $q.reject('Nope!'); } }
    });
}

Upvotes: 1

Related Questions