2

My stack is: Angular.js, Karma, Karma-coverage (Istanbul) and Jasmine.

I have been running Code Coverage analysis over my app, the problem, and thus the question, is that I get Service A marked as covered by tests (in green) when it actually does not have any tests associated.

I suspect that the following scenario is to blame:

  • I know that Service A is used by Controller B.
  • Controller B is covered by tests, and the Code Coverage results mark it correctly as covered by tests.
  • Service A is not being mocked when testing Controller B.

I think that since service A is indirectly called by Controller B's tests, I get the wrong result.

Any ideas? Am I suspecting the right thing? Is there any ways around it so I can get an accurate test coverage result in this aspect?

Thanks in advance!

1 Answer 1

3

Unfortunately, this is how code coverage is evaluated. If the code is executed, it is considered to be "covered". Luckily, there is something you can do to reduce some of the false positives. You can mock out your dependencies!

The following example will execute a jasmine spy instead of the actual service:

describe('Controller Tests', function() {
  var $scope, mockServiceA;

  beforeEach(module('app', function($provide) {
    mockServiceA = jasmine.createSpyObj('mockServiceA', ['foo']);
    $provide.value('ServiceA', mockServiceA);
  }));

  beforeEach(inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();
    $controller('ControllerB', {
      $scope: $scope
    });
  }));

  describe('ControllerB', function() {
    it('should call mock service', function() {
      expect(mockServiceA.foo).not.toHaveBeenCalled();
      $scope.useServiceA();
      expect(mockServiceA.foo).toHaveBeenCalled();
    });
  });
});

Here is a working Plunker: http://plnkr.co/edit/x8gQQNsHT0R5n5iJSxKw?p=info

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

3 Comments

Thank you for you answer! Mocking rocks! But sometimes mocking complex components that have a lot of dependencies is too obtrusive. It is good to have this in mind when evaluating and analyzing Code coverage reports.
An alternative approach to mocking the service, as described above, would be to spyOn().and.callFake(). I have found that unit tests end up being a little more work than the code they are testing but that is the price we pay for stability.
Thanks! For those who are interested, this is the link to Jasmine's doc about spies jasmine.github.io/2.0/introduction.html#section-Spies

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.