Question

J'utilise Jasmine pour tester si certains objets sont créés et les méthodes sont appelées sur eux.

J'ai un jQuery widget qui crée des objets flipcounter et appelle la méthode setValue sur eux. Le code flipcounter est ici: https: // bitbucket.org/cnanney/apple-style-flip-counter/src/13fd00129a41/js/flipcounter.js

Les flipcounters sont créés à l'aide:

var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});

Je veux tester que les flipcounters sont créés et la méthode setValue est appelée sur eux. Mon problème est que comment puis-je espionner ces objets avant même qu'ils sont créés? Est-ce que j'espionne sur le constructeur et retour des objets faux? Exemple de code serait vraiment utile. Merci de votre aide! :)

Mise à jour:

J'ai essayé espionne la flipCounter comme ceci:

myStub = jasmine.createSpy('myStub');
spyOn(window, 'flipCounter').andReturn(myStub);

//expectation
expect(window.flipCounter).toHaveBeenCalled();

Ensuite, pour tester l'appel setValue par flipCounter:

spyOn(myStub, 'setValue');

//expectation
expect(myStub.setValue).toHaveBeenCalled();

le premier test pour l'initialisation flipCounter est très bien, mais pour tester l'appel setValue, tout ce que je reçois est une « méthode setValue () n'existe pas » d'erreur. Est-ce que je fais ce la bonne voie? Merci!

Était-ce utile?

La solution

flipCounter is just another function, even if it also happens to construct an object. Hence you can do:

var cSpy = spyOn(window, 'flipCounter');

to obtain a spy on it, and do all sorts of inspections on it or say:

var cSpy = spyOn(window, 'flipCounter').andCallThrough();
var counter = flipCounter('foo', options);
expect(cSpy).wasCalled();

However, this seems overkill. It would be enough to do:

var myFlipCounter = new flipCounter("counter", options);
expect(myFlipCounter).toBeDefined();
expect(myFlipCounter.getValue(foo)).toEqual(bar);

Autres conseils

I would suggest using jasmine.createSpyObj() when you want to mock objects with properties that need to be spied on.

myStub = jasmine.createSpyObj('myStub', ['setValue']);
spyOn(window, 'flipCounter').andReturn(myStub);

This tests interactions with the expected flipCounter interface, without depending on the flipCounter implementation.

The following does not rely on 'window'. Lets say this is the code you want to test -

function startCountingFlips(flipCounter) {
    var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
}

Your test could be -

var initSpy = jasmine.createSpy('initFlipCounter');
var flipCounter = function(id, options) {
    initSpy(id, options);
}
startCountingFlips(flipCounter);
expect(initSpy).toHaveBeenCalledWith("counter", {inc:23, pace:500});

You have to implement a fake constructor for flipCounter that sets the setValue property to a spy function. Let's say the function you want to test is this:

function flipIt() {
  var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
  myFlipCounter.setValue(100);
}

Your spec should look like this:

describe('flipIt', function () {
  var setValue;
  beforeEach(function () {
    setValue = jasmine.createSpy('setValue');
    spyOn(window, 'flipCounter').and.callFake(function () {
      this.setValue = setValue;
    });
    flipIt();
  });
  it('should call flipCounter constructor', function () {
    expect(window.flipCounter)
      .toHaveBeenCalledWith("counter", {inc: 23, pace: 500});
  });
  it('should call flipCounter.setValue', function () {
    expect(setValue).toHaveBeenCalledWith(100);
  });
});

My version to test a constructor is to spy on the prototype:

spyOn(flipCounter.prototype, 'setValue').and.callThrough();
var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
expect(flipCounter.prototype.setValue).toHaveBeenCalledTimes(1);

Don't know how to do this using jasmine mocks, but if you want powerful mocking/spy/stubs I recommend sinon.js, wich works very well with jasmine.

From docs:

A test spy is a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls. A test spy can be an anonymous function or it can wrap an existing function.

Mocks (and mock expectations) are fake methods (like spies) with pre-programmed behavior (like stubs) as well as pre-programmed expectations. A mock will fail your test if it is not used as expected.

With sinon.js you could create a mock of the flipCounter constructor that returns another spy.

Then assert that the constructor was called using constructorMock.calledWithNew(), and assert that the returned spy was called with returnedSpy.calledWith(arg1, arg2...).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top