1

I can't get these two spec files to play well with each other. I didn't think spec files would effect other spec files but in this case it seem like they do, it makes no sense to me.

I'm using Jasmine and Karma the tests are automated with Gulp
The error I'm getting is "Unknown provider: ProductServiceProvider <- ProductService"

I have changed the tests to troubleshoot the issue here is the simple versions.

If I comment out the following line in file 2 both files pass.

angular.module('eu.product.service', []);

It has something to do with mocking the module but I can't figure out what I'm doing wrong here.

spec file 1

describe('Testing euProduct', function(){

var $factory;
var $httpBackend;

beforeEach(function () {

    //modules
    module('eu.product.service');

    //injections
    inject(function($injector){
        $factory = $injector.get('ProductService');
        $httpBackend = $injector.get('$httpBackend');
    });

    //mock data
    $httpBackend.when('GET', '/Mercury/product/list/0/0?PrimaryCategoryID=0&pageSize=20&startPage=1').respond({
        "data":
            [{
                "recallid":45,
            }]
    });

});

afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
});
//-----Tests----

it('Should be able to get data from the server on default parameters.', function(){
    $factory.list({},function(data){
        expect(data.data[0].recallid).toBe(45);
    });
    $httpBackend.flush();
});

});

Spec file 2

'use strict';

describe('Testing euProduct Logic', function(){

//variables in closure scope so they can be used in tested but set with injection in beforeEach
var $factory;

//mocking a module :: http://www.sitepoint.com/mocking-dependencies-angularjs-tests/
beforeEach(function () {
    angular.module('eu.product.service',[]);

    module(function($provide) {
        $provide.factory('ProductService', function() {
            // Mocking utilSvc
            return {
                list : function(para, callback){
                    callback({
                        data : {
                            product : 'The product Name'
                        }
                    })
                }
            };
        });

        $provide.service('storageSvc', function() {
            // Mocking storageSvc
        });
    });

    //modules
    module('eu.product.logic');

    //injections
    inject(function($injector){
        $factory = $injector.get('ProductLogic');
    });

});

//-----Tests----

it('Should be able to run tests', function(){
    expect(2).toBe(2);
});
});
4
  • do load module like this angular.module('eu.product.service') Mar 25, 2016 at 13:26
  • I'm shooting for mocking the module not importing it so if there is an error with the eu.product.service module it would not show up in the eu.service.logic test. How would you mock it rather then importing it. Mar 25, 2016 at 13:28
  • the way you are currently doing is, creating new module which is flushing out all registered components of it.. what you wanted to mock in eu.product.service? Mar 25, 2016 at 13:30
  • I edited the post so you can see how I'm mocking it. Mar 25, 2016 at 13:37

1 Answer 1

1

Both module and inject from angular-mocks return functions which need to be called.

In the following example I made these changes:

  • Refactor to a basic working example
  • Don't define custom $-prefixed variables. These are reserved by angular.
  • Use inject to inject instead of $injector.
  • Add some comments for further explanation.

    describe('ProductService', function() {
        var ProductService;
        var $httpBackend;
    
        // Start module config phase.
        beforeEach(module('eu.produce.service', function($provide) {
            // Inject providers / override constants here.
            // If this function is empty, it may be left out.
        }))
    
        // Kickstart the app and inject services.
        beforeEach(inject(function(_ProductService_, _$httpBackend_){
            ProductService = _ProductService_;
            $httpBackend = _$httpBackend_;
        });
    
        beforeEach(function() {
            // Optionally use another beforeEach block to setup services, register spies, etc.
            // This can be moved inside of the inject function as well if you prefer.
            //mock data
            $httpBackend.when('GET', '/Mercury/product/list/0/0?PrimaryCategoryID=0&pageSize=20&startPage=1').respond({
                "data":
                    [{
                        "recallid":45,
                    }]
            });
        });
    
        afterEach(function() {
            $httpBackend.verifyNoOutstandingExpectation();
            $httpBackend.verifyNoOutstandingRequest();
        });
    
        //-----Tests----
    
        it('Should be able to get data from the server on default parameters.', function(){
            ProductService.list({},function(data){
                expect(data.data[0].recallid).toBe(45);
            });
            $httpBackend.flush();
        });
    });
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.