I'm writing an angular controller, which has a depenedency on a dataservice (data service goes to http server), and I would like to mock its behavior.
I'm mocking with a library called bard js, and it has an api to mock services called bard.mockService.
In the beforeEach statement I'm doing:
beforeEach(function() {
bard.appModule('app.process.creation');
bard.inject('$controller', '$rootScope', '$q', 'processCreationDataservice');
bard.mockService(processCreationDataservice, {
createProcess: $q.when({}),
_default: $q.when([])
});
controller = $controller('ProcessCreationController');
$rootScope.$apply();
});
then my test:
it('should call create process data service to create process', function() {
controller.create();
expect(processCreationDataservice.createProcess).to.have.been.calledOnce;
});
As you can see in the test I want to assert that dataservice.createProcess is being called once.
The controller is not calling the method processCreationDataservice.createProcess, and still the test is passing.
(function() {
angular
.module('app.process.creation')
.controller('ProcessCreationController', ProcessCreationController);
ProcessCreationController.$inject = ['processCreationDataservice'];
function ProcessCreationController(processCreationDataservice) {
var vm = this;
vm.process = {
name: '',
bankId: ''
};
vm.create = function() {
};
}})();
I would like to know why this test is passing, and what should I do to assert that the method is being called once.
I followed these instructions: https://github.com/wardbell/bardjs#mockService
I believe that you neglected to load the sinon-chai script. You can quickly find out by pasting the following in your specs.html just below where you load sinon.js
I'll bet your test fails, exactly as you would expect.
The omission of sinon-chai leads to a very subtle false positive. Follow me as as I explain:
Let's look at the assertion/expectation just before you say "calledOnce":
It returns a chai
Assertion
. But thatAssertion
object lacks all of the sinon assertion methods such ascalledOnce
. The sinon-chai library extends chai with the sinon assertion methods.So when you tack
calledOnce
to the end, you get:Yup, the statement returns
undefined
... which is an inert statement of no consequence to mocha. It's not an error. It's just a no-op. So theexpect
does nothing and mocha thinks the test passed.You might as well have done this (it passes too):
You don't have to use "sinon-chai". It's a convenience. But if you leave it out, you'll have to write the expectation this way:
I created a plunker for you (and others) to explore these dynamics.