I'm new to TDD and I am trying to write testable code which uses a third party libraries (cross platform mobile development). I would like to have tests to only to check our business logic. Not to worry about their implementation.
More over their libraries are exposed only in native wrappers. Since use js as development language I would like to test using jasmine and run test to check my business logic only in browser.
Here are the patterns of methods I would like to ignore/mock when testing.
panyname.checkInternetAvailable(url)
panyname.store.getValue(key)
panyname.someother.name(whateverObj, callback) etc.,
At the moment, I have created a new mocks.js
file where I simply wrote
var = {
"net":{},
"store":{},
"someother":{}
}
.checkInternetAvailable = function(url){
//TODO: fix this!
return true;
}
and I do the same for all the methods in my code. I tried to use Jasmine SpyOn(, "checkInternetAvailable").and.returnValue(true)
instead of defining all the methods. Problem with this approach is I had to define all the methods to use SpyOn
.
Is there a simpler way to do this? What is the remended approach?
I'm new to TDD and I am trying to write testable code which uses a third party libraries (cross platform mobile development). I would like to have tests to only to check our business logic. Not to worry about their implementation.
More over their libraries are exposed only in native wrappers. Since use js as development language I would like to test using jasmine and run test to check my business logic only in browser.
Here are the patterns of methods I would like to ignore/mock when testing.
.panyname.checkInternetAvailable(url)
.panyname.store.getValue(key)
.panyname.someother.name(whateverObj, callback) etc.,
At the moment, I have created a new mocks.js
file where I simply wrote
var = {
"net":{},
"store":{},
"someother":{}
}
.checkInternetAvailable = function(url){
//TODO: fix this!
return true;
}
and I do the same for all the methods in my code. I tried to use Jasmine SpyOn(, "checkInternetAvailable").and.returnValue(true)
instead of defining all the methods. Problem with this approach is I had to define all the methods to use SpyOn
.
Is there a simpler way to do this? What is the remended approach?
Share Improve this question edited Apr 14, 2016 at 22:35 Ben Smith 20.3k6 gold badges73 silver badges97 bronze badges asked Mar 10, 2016 at 20:01 palanirajapalaniraja 10.5k5 gold badges45 silver badges78 bronze badges 3- hi @palaniraja. How are those third party modules included? do you have the entire object in your code? – Tokimon Commented Apr 14, 2016 at 16:38
- Yes @Tokimon When I run them inside native wrapper, I have the entire object. I believe they run webkit engine in the background to execute the code. But my reqd. is just to mock all the calls with my stub method to check the order of method calls and verify all the expected methods are called. – palaniraja Commented Apr 14, 2016 at 21:58
-
hi @palaniraja, normally i would loop all properties on the object and child objects and stub each of them with your
function() { return true; }
(or a sinon stub), but that only works if you don't care which one is called and just want them all to return true. If you need to check that specific methods are called, then you need to specify in your test which ones you expect to be called. – Tokimon Commented Apr 15, 2016 at 8:44
1 Answer
Reset to default 5 +50One approach you could take is to use the Sinon javascript test library to stub the third party library methods. These stubbed methods can then be set-up to mimic results which would be difficult to reproduce using the actual third party library. Your system under test (SUT) could then make use of these stubbed methods inside of your Jasmine tests.
I've written a contrived example here:
https://jsfiddle/Fresh/uf8owzdb/
The code is as follows:
// A module which has methods you want to stub
Net = (function() {
// Constructor
function Net() {
}
Net.prototype.checkInternetAvailable = function(url) {
return true;
};
return Net;
})();
// A method which is dependent on the Net module
var methodWhichUsesNet = function(net) {
return net.checkInternetAvailable();
};
// Stub the method behaviour using Sinon javascript framework.
// For the test, get it to return false instead of true.
var net = new Net();
var expectedResult = false;
sinon.stub(net, "checkInternetAvailable").returns(expectedResult);
// Assert method behaviour using a Jasmine test
describe("Net test suite", function() {
it("methodWhichUsesNet should return expected result", function() {
expect(methodWhichUsesNet(net)).toBe(expectedResult);
});
});
Note that it is advisable to stub the third party methods as you want to control exactly what they should return, as you know which methods your code is making use of. Alternatively you could mock these third party methods if you also want to verify that these methods are called by the method which uses them. You could stub the entire third party object methods using e.g.:
var stub = sinon.stub(obj);
However I would advise against doing this as it would mean that the test would not be as explicit i.e. you would not be sure as to how the stubbed methods are behaving, whereas stubbing them explicitly means you have plete control of their behaviour.