user339827
user339827

Reputation:

Async test with Jasmine

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

Answers (3)

user339827
user339827

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

Ahmed Nuaman
Ahmed Nuaman

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

John Tseng
John Tseng

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

Related Questions