How can I test that an element fired an event with mocha? I've got an ugly solution working, but it's not very readable, takes a long time to time out when it fails, and doesn't give good failure messaging.
describe('test-element', function() {
var el;
beforeEach(function() {
el = document.createElement('test-element');
});
it('fires a save event', function(done) {
el.addEventListener('save', function() {
done();
});
el.save();
});
In a perfect world, I think something like this would be cooler.
it('fires a save event', function() {
el.save();
expect(el).to.have.firedEvent('save');
});
});
Am I going about this the right way? Is there a better approach or a custom matcher library I should be using?
How about spying on the fire function...?
Not sure what stubbing/spying library you're using but lets say Sinon.JS. So something like...
var spy = sinon.spy(el, 'fire');
el.save();
expect(spy.calledWith('save')).to.be.true;
Related
I have a problem in my automatic test scenario when I try to call my function costumtra using webdriver.io.
I want that the scenario waits until the method call finish
describe('senario', function() {
it('can click submit button', function() {
// Do something
browser.costumtra(browser.element('#submit'));
// Do something
}
});
browser.addCommand("costumtra", function(element) {
// Do something
}
any solution please ?
You can define custom commands at any point in your test suite, just make sure that the command is defined before you first use it (the before hook in your wdio.conf.js might be a good point to create them). Also to note: custom commands, like all WebdriverIO commmands, can only be called inside a test hook or it block. May be your are calling the test method before define it. change it as given below.
browser.addCommand("costumtra", function(element) {
// Do something
}
describe('senario', function() {
it('can click submit button', function() {
// Do something
browser.costumtra(browser.element('#submit'));
// Do something
}
});
I'm trying to optimise my Angular app and browsing several websites I found this practice too:
var cleanup = $scope.$on('someEvent', function() {
$scope.refresh();
});
$scope.$on('$destroy', function() {
cleanup();
});
Due to the fact I have several $scope.$on in my controllers I was wondering if it is correct to use it like this:
var first = $scope.$on('firstEvent', function() {
$scope.something1();
});
var second = $scope.$on('secondEvent', function() {
$scope.something2();
});
var third = $scope.$on('thirdEvent', function() {
$scope.something3();
});
$scope.$on('$destroy', function() {
first();
second();
third();
});
Is this good to implement and correct?
As cited article says,
Angular should clean this up if you forget to, but the advice is always do it yourself.
Putting safeguards around the expected framework behaviour is overcautious and can hardly be called a good practice.
While jQuery/jqLite (element.on) and third-party event listeners may lead to memory leaks and should be cleaned up on scope $destroy or element $destroy event.
My project contains an external library that use async XMLHttpRequest to load data. The loading time can vary between 200ms to 10000ms.
I would like Jasmine to perform the tests only when that library has finished loading.
I am a little bit confuse with the Async testing in Jasmine. I would like to have only one timeout that will wait beforeAll tests, then perform each test synchronously.
Is it possible? I have something like below, but it's not working.
describe("External library cartovista", function() {
beforeAll(function(done){
var cartovista = window.cartovista;
done();
}, 10000);
it("cartovista should be loaded", function(done) {
expect(cartovista).toBeDefined();
done();
});
it("cartovista component and data working as wanted", function(done) {
//an example of testing over the data
var data = cartovista.data[0]
expect(cartovista.afunction(data)).toBe(true);
done();
});
//etc...
});
Edit: I have to mention that I want to perform the tests with the real data.
I have found a way to do what I am trying to do. I was pretty close to a correct answer in my question.
Note that the DEFAULT_TIMEOUT_INTERVAL should be greater than the setTimeout interval
describe("External library cartovista", function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 11000;
var cartovista;
beforeAll(function(done){
setTimeout(function() {
cartovista = window.cartovista;
done();
}, 10000);
});
it("cartovista should be loaded", function() {
expect(cartovista).toBeDefined();
});
it("cartovista component and data working as wanted", function() {
//an example of testing over the data
var data = cartovista.data[0]
expect(cartovista.afunction(data)).toBe(true);
});
//etc...
});
See Jasmine doc
I've got a set of modules that run based on a global event emitter. They run based on a chronological chain of events, like so:
boot.ready
server created (because of boot.ready event)
server configured (because of server.created event)
As such, I need to create a server-test.js that performs tests in a chronological order.
Is this possible with Mocha? Something like the following?
var EventEmitter2 = require('eventemitter2').EventEmitter2,
should = require('should');
describe('server', function() {
var mediator = new EventEmitter2({
wildcard: false
});
require('../../src/routines/server/creator')(mediator);
require('../../src/routines/server/configurer')(mediator);
it('should be created after boot', function(done) {
mediator.once('server.created', function(server) {
server.should.exist;
done();
});
it('should be configured after created', function(done) {
mediator.once('server.configured', function() {
done();
});
});
mediator.emit('boot.ready');
});
});
Because there seemed to be some confusion about the way this global event emitter works, this is the server/creator.js module:
module.exports = function(mediator) {
var express = require('express');
mediator.once('boot.ready', function() {
var server = express.createServer();
//event: server created
mediator.emit('server.created', server);
});
};
As you can see, the server is created after boot.ready. This fires server.created, after which the configurer will run which will then fire server.configured.
This chain of events needs to be tested by mocha.
If I'm testing a chain of events the quick way is to do it is nested eventEmitter.once calls like this:
it('executes in the right sequence', function(done) {
mediator.once('boot.ready', function() {
mediator.once('server.created', function() {
done()
})
})
})
edit: as pointed out server.created will be fired before the test's boot.ready handler is fired. Here's a workaround:
it('executes in the right sequence', function(done) {
var bootReadyFired = false
mediator.once('boot.ready', function() {
bootReadyFired = true
})
mediator.once('server.created', function() {
assert.ok(bootReadyFired)
done()
})
})
Hope this helps.
Actually mocha use function.length to your it callbacks to know if you want them asynchronously, so with function(done) you can't known in which order they're run. function() without done argument will run them synchronously.
EDIT
Your mediator is an EventEmitter2 meaning that when you emit something, the handler will be run async. Like I said they's no way to known the order in which the are executed.
The problem is in you required modules, each event should probably be emitted in the handler of the previous. Code is better than words :
// require('../../src/routines/server/creator')(mediator);
// I guess this module creates the server, then it should emit server.created
// require('../../src/routines/server/configurer')(mediator)
// This one should listen to server.created then configure the server
// and finally emit server.configured
// So in it you should have something like this:
mediator.once('server.created', function(server) {
// Here you should configure you're server
// Once it is configured then you emit server.configured
});
Also you should know that emit is immediate in node so you'd better add your listeners before emitting.
Hope this is clear.
I googled on how to unit test but examples are so simple. the examples always show functions that return something or do ajax that returns something - but never have i seen examples that do callbacks, nested callbacks and functions that are "one-way", that they just store something and never return anything.
say i have a code like this, how should i go about testing it?
(function(){
var cache = {};
function dependencyLoader(dependencies,callback2){
//loads a script to the page, and notes it in the cache
if(allLoaded){
callback2()
}
}
function moduleLoader(dependencies, callback1){
dependencyLoader(dependencies,function(){
//do some setup
callback1()
});
}
window.framework = {
moduleLoader : moduleLoader
}
}());
framework.moduleLoader(['foo','bar','baz'],function(){
//call when all is loaded
})
This illustrates a problem with keeping things private in an anonymous function in javascript. It's a bit difficult to validate that things are working internally.
If this was done test first then the cache, dependencyLoader and moduleLoader should be publicly available on the framework object. Or else it would be difficult to validate that the cache was handled properly.
To get things going I'd recommend you take a gander on BDD, that conveniently gives you an approach to help you start by letting you spell out the behaviour with a given-when-then convention. I like to use Jasmine, which is a javascript BDD framework (that integrates with jstestdriver), for this kind of thing and the unit tests I'd make for the sample you have above would be:
describe('given the moduleloader is clear', function() {
beforeEach(function() {
// clear cache
// remove script tag
});
describe('when one dependency is loaded', function() {
beforeEach(function() {
// load a dependency
});
it('then should be in cache', function() {
// check the cache
});
it('then should be in a script tag', function() {
// check the script tag
});
describe('when the same dependency is loaded', function() {
beforeEach(function () {
// attempt to load the same dependency again
});
it('then should only occur once in cache', function() {
// validate it only occurs once in the cache
});
it('then should only occur once in script tag', function() {
// validate it only occurs once in the script tag
});
});
});
// I let the exercise of writing tests for loading multiple modules to the OP
});
Hope these tests are self explanatory. I tend to rewrite the tests so that they nest nicely, and usually the actual calls are done in the beforeEach functions while the validation are done in the it functions.