2

I'm part of a team that's been working on angularjs for quite a while now and our unit tests consist of files which contain both the test logic and provider mocks of each component that tested element relies on.

This is leading to more and more code duplication, can anyone recommend an angular-ey method whereby we could maintain a test infrastructure, mock a controller or service once and be able to inject that mocked service into other tests as required?

Edit The code I'm working with is proprietary but for an example consider you have 10 or 15 services which retrieve data via HTTP requests, format the data in different ways and return that data. One example might return arrays of data so in each file which relies on the service we would have initialising code like the following ( cut down and altered so please ignore any typos or other mistakes )

myDataService: {
    getDataParsedLikeY: {
        [{obj1},{obj2}...]
    },
    getDataParsedLikeX: {
        [{obja},{objb}...]
    }
beforeEach(angular.mock.module('myModule'));
beforeEach(angular.mock.inject(function(myDataService) {
    myDataService = function( functionName ) {
        return myDataService[functionName];
    }
    spyOn(myDataService).and.callThrough();
})
}
4
  • Could you give us some example code that should not be duplicated for testing? Commented Apr 1, 2015 at 7:15
  • I've added what I can under the edit, hopefully it helps Commented Apr 1, 2015 at 7:33
  • @yazaki The service mocking is the code that he is trying not to duplicate all over in every controller test. Commented Apr 12, 2015 at 12:27
  • Too bad the comments at odetocode.com/blogs/scott/archive/2014/05/15/… are now closed. I would have asked Scott his take on this question. Commented Apr 12, 2015 at 12:32

2 Answers 2

1

If you are looking for a way not to declare same mock codes in every test files, I would suggest something like below although I'm not sure this is angular-way or not.

[1] write the code to declare your mock services like below only for unit test and import after angular-mocks.js

In your-common-mocks.js(you can name the file as you like)

(function(window){
    window.mymock = {};
    window.mymock.prepare_mocks = function(){
        module(function($provide) {
            $provide.service('myDataService', function(){
                this.getDataParsedLikeY = function(){
                    return 'your mock value';
                };
            });
        });
    };
})(window);

If you use karma, you could write like this to import the file in karma.conf.js.

files: [
  ...
  '(somedirctory)/angular-mocks.js',
  '(somedirctory)/your-common-mocks.js'
  ...
]

[2] use mymock.prepare_mocks function in your test files.

describe('Some Test', function() {

    beforeEach(mymock.prepare_mocks);

    it('getDataParsedLikeY', inject(function(myDataService){
        expect('your mock value', myDataService.getDataParsedLikeY());

As a result of above, you have to write your mock code just one time and share the mock code in your every test files. I hope this could suggest you something to achieve what you want.

Sign up to request clarification or add additional context in comments.

Comments

0

If your jasmine version is 2.x, you can write test code like below without writing mock service.

spyOn(YourService, 'somemethod').and.returnValue('mock value');

In jasmine 1.3 you need to adjust little bit.

spyOn(YourService, 'somemethod').andReturn('mock value');

I hope this could help you.

2 Comments

Thank you for your answer, unfortunately I'm looking for a way to not have to declare this spy in every place where the service is used as these datasets can be very large
Also, I understand spies are unable to deal with a service that have multiple callbacks, say, like one having a success callback and a failure callback. This makes spies useful for simple services, but a proper mock is mandated for more complex services.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.