Reputation:
I'm trying to do some test with Jasmine and RequireJS. Everything was going really well until I noticed that I had a problem regarding the context of the functions I was describing.
I'm doing some Ajax test so, the first thing I do is to set up a listener for the success, then requesting that service. Then, inside each of my it()
declarations I do my tests based on the service response.
Here are my spec modules:
// auth.js
define(['service/auth'], function(auth) {
describe('Tests "auth" service', function() {
var data;
var OPTIONS = {
CN: '147144147',
GV: '147153162'
};
auth.on.success.addOnce(function(response) {
data = response;
});
auth.request(OPTIONS);
it('"status" should exist and be "true"', function() {
waitsFor(function() {
return data !== undefined;
});
runs(function() {
expect(data['status']).toBeDefined();
expect(data['status']).toBeTruthy();
});
});
});
});
// login.js
define(['service/login'], function(login) {
describe('Tests "login" service', function() {
var data;
var OPTIONS = {
oper: 1,
codigoouemail: '101',
senha: '10151015'
};
login.on.success.addOnce(function( response ) {
data = response;
});
login.request(OPTIONS);
it('Should get the service response for user "' + OPTIONS.codigoouemail + '"', function() {
waitsFor(function() {
return data !== undefined;
});
runs(function() {
expect(data).toBeDefined();
});
});
});
});
They both work fine when tested individually but what I noticed is that they share the same value for data
. The first module to run, sets its value and the other specs will have the same value. I need to have a single value per module so I can test each service response properly.
In theory, every module should have its own scope but doesn't look like this is happening.
Someone have any idea on how to solve this?
Upvotes: 2
Views: 2450
Reputation:
So this was totally my bad. It was an error on the ajax call, which was giving me always the same value and therefore failing all the tests. Thanks for the help anyway :)
Upvotes: 1
Reputation: 13261
So here's an example of an async test I use to check if my VOs
are created:
it('should return a list of item VOs', function() {
var dfd = $q.defer();
var items = mock.content.items[1].items;
runs(function() {
dfd.promise.then(function(VOs) {
expect(VOs.length).toBe(items.length);
expect(A.equals(itemVO(items[0]), VOs[0])).toBe(true);
}, this.fail);
});
waits(50);
runs(function() {
itemsVO(dfd, items);
$rootScope.$digest();
});
});
So first I run a function to listen to when my async function has completed, I wait 50ms to check that the app is ready and then I run my async function. Notice how the expect
is in the callback.
Upvotes: 1
Reputation: 6352
Sorry to say, but the problem is not in the data variable. Javascript has function scope, so the two data variables are different. Here's a fiddle showing that data is not the same: http://jsfiddle.net/LNuHU/2/
Below is the code:
//--- SPECS -------------------------
describe('Tests timeout service 1', function() {
var data;
setTimeout(function( response ) {
data = 3;
}, 1000);
it('Should be 3', function() {
waitsFor(function() {
return data !== undefined;
});
runs(function() {
expect(data).toBe(3);
});
});
it('Should be 30', function() {
waitsFor(function() {
return data === 30;
});
runs(function() {
expect(data).toBe(30);
});
});
});
describe('Tests timeout service 2', function() {
var data;
setTimeout(function( response ) {
data = 30;
}, 2000);
it('Should be 30', function() {
waitsFor(function() {
return data !== undefined;
});
runs(function() {
expect(data).toBe(30);
});
});
it('Should be 30', function() {
waitsFor(function() {
return data === 3;
});
runs(function() {
expect(data).toBe(3);
});
});
});
Upvotes: 0