最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to mock only one method using Sinon? - Stack Overflow

programmeradmin4浏览0评论

I've got a single method in my namespace that I'd like to mock, but I'd prefer that all the others work normally. Is it possible to have sinon mock a specific method while leaving the others the same?

My understanding is I'm not looking for a spy because I want to assert that the mock was called with specific parameters.

Here's my code in CoffeeScript:

root.targeting.handleUnitsAttack = (gameState) ->
  units = gameState.heroes.concat(gameState.badGuys)
  for source in units
    for target in units
      gameState = root.targeting.sourceAttackTarget(gameState, source, target)
  gameState

I'd like to mock sourceAttackTarget and verify that its arguments are specific values.

I've got a single method in my namespace that I'd like to mock, but I'd prefer that all the others work normally. Is it possible to have sinon mock a specific method while leaving the others the same?

My understanding is I'm not looking for a spy because I want to assert that the mock was called with specific parameters.

Here's my code in CoffeeScript:

root.targeting.handleUnitsAttack = (gameState) ->
  units = gameState.heroes.concat(gameState.badGuys)
  for source in units
    for target in units
      gameState = root.targeting.sourceAttackTarget(gameState, source, target)
  gameState

I'd like to mock sourceAttackTarget and verify that its arguments are specific values.

Share Improve this question edited Nov 7, 2018 at 17:59 k0pernikus 66.7k77 gold badges242 silver badges361 bronze badges asked Jul 24, 2014 at 2:14 Daniel KaplanDaniel Kaplan 67.4k57 gold badges268 silver badges399 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

Yes, that is one of the most mon uses cases for sinon@2, but I believe that what you are looking for is neither a mock nor a spy, but instead a stub.

See: https://sinonjs/releases/v2.4.1/stubs/

var stub = sinon.stub(object, "foo");
//do your assertions
stub.restore(); //back to normal now.

This will allow you to create a default function that replaces object.foo().

From your question, however, it sounds like a no-op stub function is not what you are after, and instead want to override it with a custom function of your own:

var stub = sinon.stub(object, "foo", function customFoo() { /* ... */ });
//do your assertions
stub.restore(); //back to normal now.

HTH!


EDIT:

How to stub a single function:

The following stubs object.sourceAttackTarget()

var stub = sinon.stub(object, "sourceAttackTarget", function sourceAttackTargetCustom(gameState, source, target) {
    //do assertions on gameState, source, and target
    // ...
    return customReturn;
});
//do any further assertions
stub.restore(); //back to normal now.

How to stub a function to test for particular parameters

var stub = sinon.stub(object, "sourceAttackTarget");
stub.withArgs(1, "foo", "bar").returns("correctTarget");
stub.returns("wrongTarget");
var output = object.sourceAttackTarget(gameState, source, target);
equal(output, "correctTarget", 'sourceAttackTarget invoked with the right arguments');
//do any further assertions
stub.restore(); //back to normal now.

(Update)

There is also .calledWith() and .calledWithMatch(), which I just found out about. Could also prove quite useful for these sorts of tests.

How to mock just one method for an object:

"Mocks e with built-in expectations that may fail your test. Thus, they enforce implementation details. The rule of thumb is: if you wouldn’t add an assertion for some specific call, don’t mock it. Use a stub instead. In general you should never have more than one mock (possibly with several expectations) in a single test." - source

... so for the question asked above, a mock is not the right thing to use, and a stub is the appropriate choice. That being said, one of the scenarios can be tested easily with a mock, and that is the expectation that a method has been called with a particular set of arguments.

var mock = sinon.mock(object);
mock.expects("sourceAttackTarget").withArgs(1, "foo", "bar");
object.sourceAttackTarget(gameState, source, target);
mock.verify();

Starting with [email protected], the

var stub = sinon.stub(object, "method", func);

has been removed. One should rather use:

stub(object, "method").callsFake(func)
stub.callsFake(fakeFunction);
Makes the stub call the provided fakeFunction when invoked.

var myObj = {};
myObj.prop = function propFn() {
    return 'foo';
};

sinon.stub(myObj, 'prop').callsFake(function fakeFn() {
    return 'bar';
});

myObj.prop(); // 'bar'

Source: sinonjs docs

const { foo } = require('../some.js');
const service = { foo };
const stub = sinon.stub(service, "foo");

It normally expects an object where foo needs to be part of it. Simply declare an object by yourself, add the function as a property, and then use it while stubbing.

发布评论

评论列表(0)

  1. 暂无评论