how to do a mock test with polymer - javascript

I have a function, is a function of polymer web component custom.
getListDedications: function(e){
var idDate = e.model.__data__.date.data.id;
var checkId = function(element){
return element.id == idDate;
};
var responseID = this.dedications.filter(checkId);
this.data = JSON.stringify(responseID[0].entries) || [];
console.log(JSON.stringify(responseID[0].entries) || []);
}
This function return a array or an array empty.
I want to test it, I'm using web-component-tester and I run the tests with gulp test:local.
I know that I need to mock e.model.__data__.date.data.id but I do not know how

Web component tester comes with sinon and sinon-chai bundled in it now.
You don't say what e.model._data__.date.date.id is. Obviously if its just data, you set it up and then call getListModifications with the a parameter. However, if its a function then use sinon stub (or spy) with
var sandbox;
beforeEach(function(){
sandbox = sinon.sandbox.create();
});
afterEach(function(){
sandbox.restore();
});
it('should ...',function(){
var e = sandbox.stub().returns('whatever data you want');
var answer = getListDedications(e);
expect(answer).to.be.an('Array');
});

Related

Using external class during client side Mocha unit testing

I am running unit tests on a javascript class using Mocha using the follow methodology, firstly the test:
var base = require('../moduleone.js');
describe("some test", function() {
it("description", function() {
var check = base.toBeTested(dummyValue)
//test is here ...
});
});
the moduleone.js containing function to be tested:
function toBeTested(category){
//below I calling an assert function defined in moduletwo
//works fine when running in browser
assert(type(category)=='string','category is string type');
//more code..
return something
module.exports.toBeTested = toBeTested;
moduletwo.js:
function assert(outcome, description) {
//see code.tutsplus.com quick and easy javascript testing with assert
var li = outcome ? 'pass' : 'fail';
if (li == 'fail') {
console.log('FAIL: '+description);
}
else {
console.log('PASS: '+description);
}
}
The issue I have is mocha doesn't know anything about moduletwo and when the moduleone function calles the function in moduletwo mocha throws a ReferenceError: assert is not defined. How can I link all my dependencies so that mocha can see them?
In your moduleone.js be sure that you are requireing moduletwo.js to bring your assert function into scope for moduleone.js. Otherwise, you get a ReferenceError, not for any reasons with mocha, but because moduleone does not have access to assert.
// moduletwo.js
function assert(outcome, description) { /* your functionality */ }
module.exports = assert
// moduleone.js
var assert = require('./moduletwo')
function toBeTested(category) { /* your functionality that uses assert */ }
module.exports.toBeTested = toBeTested
Now, with regards to that tutorial. If you are following it to learn how to make an easy assert module, that is fine. But if you are trying to test some code that does something else, consider using an existing assertion library like chai. For example:
// example.test.js
var expect = require('chai').expect
var isValidCategory = require('./is-valid-category')
describe('isValidCategory(category)', function () {
it('validates string categories', function () {
expect(isValidCategory('A String Category')).to.be.true
})
it('does not validate non-string categories', function () {
expect(isValidCategory(['an', 'array', 'somehow'])).to.be.false
})
})
// is-valid-category.js
module.exports = function isValidCategory(category) {
return typeof category === 'string'
}

Mocha tests mocking function

I'm testing backbone view, that have function:
attachSelect: function(id, route) {
console.log(id);
console.log(route);
this.$(id).select2({
ajax: {
url: route,
dataType: 'json',
results: function(data) {
var results = _.map(data, function(item) {
return {
id: item.id,
text: item.title
};
});
return {
results: results
};
},
cache: true
}
});
}
I need to rewrite (mock) this fuction that, the looks like:
attachSelect: function(id, route) {
console.log(id);
console.log(route);
}
How to do that ?
The simplest way to mock a function is to replace the property at runtime.
You can provide your own monitoring function (commonly called a spy), although this is not the most elegant. That would look like:
var called = false;
var testee = new ViewUnderTest();
var originalAttach = testee.attachSelect; // cache a reference to the original
testee.attachSelect = function () {
called = true;
var args = [].concat(arguments); // get an array of arguments
return originalAttach.apply(testee, args);
};
// Perform your test
expect(called).to.be.true;
If you have a test assertion library like chai, you can use the spies plugin and reduce that to:
var testee = new ViewUnderTest();
var spy = chai.spy(testee.attachSelect);
testee.attachSelect = spy;
// Perform your test
expect(spy).to.have.been.called();
Using a spy library will provide some useful features, such as monitoring the number of calls and their arguments to verify low-level behavior. If you're using Chai or Jasmine, I would highly suggest taking advantage of the corresponding support for spies.

How to organize code for unit testing BDD using Mocha Chai?

I trying unit testing using Mocha/Chai using BDD style. Not sure where to start. Following is what the core code structure is. Assuming that getTemplates is an ajax call, how do I the different stages of an application. For i.e. before hitting sh.setTemplates() in init function, it has go through few conditions. How to unit test those conditions?
// Javascript
function myFunc(id){
var mf = this;
mf.id = id;
mf.init = function(){return init()};
mf.isIdValid = function(){return isIdValid()};
mf.setTemplates = function(){return setTemplates};
mf.getTemplates = function(){return getTemplates};
// Init
mf.init();
///////////////////////
function init(){
if(!id){
return false;
}
if(!sh.isIdValid()){
return false;
}
sh.setTemplates();
}
///////////////////////
function setTemplates(){
getTemplates(function(callBackTemplate){
if(!callbackTemplate){
return false;
}
// inject to dom
});
}
///////////////////////
// Async call
function getTemplates(){
return '<div>Test</div>';
}
}
///////////////////////////////////////
/////////////////////////////////////////
TEST JS Mocha/Chai
var expect = chai.expect;
describe('myFunc Class', function(){
var mf;
before(function(){
mf = new myFunc(1);
});
describe('mf.init()', function(){
it('should not result false', function(){
var result = mf.init();
expect(result).to.not.equal(false);
});
});
How to unit test those conditions?
Use the following process:
Create a branch function
Put the assertion in the branch function
Use the variant as an argument
Call it once with a truthy value
Call it again with a falsy value
References
BDD and Fluent Assertions
Eclipse Orion: Running the Tests

Accesing a backbone view's function to make a sinon stub

Am working on Backbone application and i have to unit test it using sinon.js and Qunit.js.
The scenario is i have one carView which extends baseview and the baseview extends backbone's view.
I have one function say buildFormUrl in the car view which returns a string. The string value is changed on the basis of user action.
Is it possible to make stub of buildFromUrl stub using sinon.stub and calling the stub function and then checking the return values?
Backbone Code Snippet:
var CarSearchView = BaseView.extend({
intitalize : function(){
//some code
},
buildFormUrl: function(baseUrl){
// process a different form url based on new/used selection
var newUsedToggleValue = this.$('#cars-form-new-used-select').val(),
url = baseUrl;
if (newUsedToggleValue === 'used') {
url += 'for-sale/searchresults.action';
} else {
url += 'go/search/newBuyIndex.jsp';
}
return url;
}
});
Sinon code Snippet:
QUnit.test('_buildURLForm function', function(){
QUnit.expect(1);
var BuildFormURLStub = Sinon.stub(CarSearch.prototype, 'buildFormUrl');// building the sinon stub
var toggleButton = $(SampleHtml).find('cars-new-used-toggle');
$(toggleButton).first().click(); //clicking the button
var baseURL = "http:\\www.cars.com";
var output = Sinon.once(BuildFormURLStub.withArgs(baseURL)); // passing the argument and and calling the function using sinon once![enter image description here][1]
var Expected = baseURL + 'for-sale/searchresults.action';
QUnit.deepEqual(output,Expected,"For new Toggle button clicked");
});
Am getting the error " The function is undefined"
'undefined' is not a function (evaluating 'Sinon.once(BuildFormURLStub.withArgs(baseURL))')
TypeError: 'undefined' is not a function (evaluating 'Sinon.once(BuildFormURLStub.withArgs(baseURL))')
You need to pass in an object instead of the prototype:
var carSearchInstance = getInstanceSomehow();
var BuildFormURLStub = Sinon.stub(carSearchInstance , 'buildFormUrl');

Is there any way to use Jasmine default matchers within custom matchers?

I have a custom matcher in some Jasmine test specs of the form:
this.addMatchers({
checkContains: function(elem){
var found = false;
$.each( this.actual, function( actualItem ){
// Check if these objects contain the same properties.
found = found || actualItem.thing == elem;
});
return found;
}
});
Of course, actualItem.thing == elem doesn't actually compare object contents- I have to use one of the more complex solutions in Object comparison in JavaScript.
I can't help but notice, though, that Jasmine already has a nice object equality checker: expect(x).toEqual(y). Is there any way to use that within a custom matcher? Is there any general way to use matchers within custom matchers?
Yes, it is slightly hacky but entirely possible.
The first thing we need to do is make the Jasmine.Env class available. Personally I have done this in my SpecRunner.html since its already setup there anyway. On the load of my SpecRunner I have the following script that runs:
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var trivialReporter = new jasmine.TrivialReporter();
jasmineEnv.addReporter(trivialReporter);
jasmineEnv.specFilter = function(spec) {
return trivialReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
};
})();
So after the execJasmine function declaration I push the jasmineEnv into the global namespace by adding this:
this.jasmineEnv = jasmineEnv;
Now, in any of my spec files I can access the jasmineEnv variable and that is what contains the matchers core code.
Looking at toEqual specifically, toEqual calls the jasmine.Env.prototype.equals_ function. This means that in your customMatcher you can do the following:
beforeEach(function(){
this.addMatchers({
isJasmineAwesome : function(expected){
return jasmineEnv.equals_(this.actual, expected);
}
});
});
Unfortunately, using this method will only give you access to the following methods:
compareObjects_
equals_
contains_
The rest of the matchers reside the jasmine.Matchers class but I have not been able to make that public yet. I hope this helps you out in someway or another

Categories

Resources