admin管理员组

文章数量:1287879

Can anyone possibly tell me why the following test fails.

var Person = function() {};

Person.prototype.helloSomeone = function(toGreet) {
  return this.sayHello() + " " + toGreet;
};

Person.prototype.sayHello = function() {
  return "Hello";
};

describe("Person", function() {
 it("calls the sayHello() function", function() {
   var fakePerson = new Person();
   spyOn(fakePerson, "sayHello");
   fakePerson.helloSomeone("world");
   expect(fakePerson.sayHello).toHaveBeenCalled();
  });
});

I took it from here and he said it works. I can see the spyOn method is creating a wrapper function of the same name on the person object i.e. fakePerson.sayHello is being invoked on the object and not the prototype.

Many thanks

Can anyone possibly tell me why the following test fails.

var Person = function() {};

Person.prototype.helloSomeone = function(toGreet) {
  return this.sayHello() + " " + toGreet;
};

Person.prototype.sayHello = function() {
  return "Hello";
};

describe("Person", function() {
 it("calls the sayHello() function", function() {
   var fakePerson = new Person();
   spyOn(fakePerson, "sayHello");
   fakePerson.helloSomeone("world");
   expect(fakePerson.sayHello).toHaveBeenCalled();
  });
});

I took it from here and he said it works. I can see the spyOn method is creating a wrapper function of the same name on the person object i.e. fakePerson.sayHello is being invoked on the object and not the prototype.

Many thanks

Share Improve this question edited Feb 22, 2012 at 14:32 screenm0nkey asked Feb 22, 2012 at 14:16 screenm0nkeyscreenm0nkey 18.8k18 gold badges62 silver badges75 bronze badges 2
  • The tests fail because I'm also using jasmine-sinon.js. Not sure why yet but the test work as soon as I remove it. – screenm0nkey Commented Feb 22, 2012 at 15:32
  • Hi screenm0nkey, you might be interested why I think that using toHaveBeenCalled isn't the best choice in this use-case: stackoverflow./a/16851650/705888 – basecode Commented Apr 25, 2014 at 2:58
Add a ment  | 

2 Answers 2

Reset to default 8

The tests failed because I was also using jasmine-sinon.js.

One possible problem with your test cases is that you haven't specified that the original method should be called. What would have a proper behavior is the following (note the "andCallThrough") :

describe("Person", function() {
 it("calls the sayHello() function", function() {
   var fakePerson = new Person();
   spyOn(fakePerson, "sayHello").andCallThrough();
   fakePerson.helloSomeone("world");
   expect(fakePerson.sayHello).toHaveBeenCalled();
  });
});

You can see the documentation page of Jasmine for more information about the other possibility : https://github./pivotal/jasmine/wiki/Spies

Edit: A quick look at the jasmine-sinon documentation brings up the following:

Warning

jasmine-sinon currently overwrites any Jasmine matchers of the same name used for its own spying features. I plan to allow these to be optionally retained in the future.

The native Jasmine matchers that are overwritten are:

  • toHaveBeenCalled()
  • toHaveBeenCalledWith()

If you want to use jasmine-sinon, you have to use their API and not the one of Jasmine.

Edit: As of Feb 2012:

You can also use Jasmine spies alongside your Sinon spies. jasmine-sinon will detect which you're using and use the appropriate matcher.

本文标签: javascriptIssues with Jasmine39s spyOn toHaveBeenCalled methodStack Overflow