Multiple, ordered return values from a stub - possible?

3,925 views
Skip to first unread message

Erin Swenson-Healey

unread,
Sep 24, 2012, 9:42:37 PM9/24/12
to sin...@googlegroups.com
Hi all,

I'm curious if there's some way I can do something like:

var myStub = sinon.stub();

myStub.withArgs(1).returns("ham"); // first call
myStub.withArgs(1).returns("sandwich"); // second call, same args

var x = myStub(1); // "ham"
var y = myStub(1); // "sandwich"

I am digging around in the API doc and can't seem to find what I'm
looking for. Any thoughts?

Take care,

Erin

Christian Johansen

unread,
Sep 25, 2012, 3:24:05 AM9/25/12
to sin...@googlegroups.com
Hi Erin,


It's not possible today. However, I recently merged a very similar feature for callbacks from Domenic Denicola: https://github.com/cjohansen/Sinon.JS/pull/173

His PR makes it so `yields` called multiple times creates a sequence. I'm open to have the same behavior for `returns` as well, i.e.:

myStub.returns(42).returns(13);

Would make the stub return 42 in the first call and 13 in the second. So, if anyone's up to the task, I'd be happy to review and eventually merge :)

Christian
 

Take care,

Erin




--
MVH
Christian

Jacob Wan

unread,
Jan 25, 2014, 9:19:28 PM1/25/14
to sin...@googlegroups.com, chri...@cjohansen.no
I'd like to see such a change, and I can't think of any harm offhand.

In the meantime, in case it helps anyone, what I normally do as a workaround is to have a method wrapping the thing I want to control, such as Math.random, and then I mock that instead.  For example,

(function() {
    test('mocking Math.random', function() {
        function ProductionClass() {}
        ProductionClass.prototype.call_random = function(min, max) {
            if ((undefined === min) || (undefined === max)) {
                return Math.random();
            }
            return Math.random() * (max - min) + min;
        };
        
        // Setup
        var test_me = new ProductionClass,
            mock_test_me = sinon.mock(test_me);
        
        mock_test_me.expects('call_random').withExactArgs(0,10).returns(0);
        mock_test_me.expects('call_random').withExactArgs(0,10).returns(1);
        mock_test_me.expects('call_random').withExactArgs(0,10).returns(2);
        
        // Code under test
        console.log(test_me.call_random(0,10)); // 0
        console.log(test_me.call_random(0,10)); // 1
        console.log(test_me.call_random(0,10)); // 2

        // Assert
        mock_test_me.verify();
    });
}());

Jacob

Maximilian Antoni

unread,
Jan 26, 2014, 2:28:04 AM1/26/14
to sin...@googlegroups.com
Hi Jacob,

There is an implementation for this in the code waiting to be released.

It's called "behaviors" and it's going to work like this:

  stub.onFirstCall().returns(1);
  stub.onCall(2).returns(2);

This will also support yields, yieldsTo and throws.

-Max
--
You received this message because you are subscribed to the Google Groups "Sinon.JS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sinonjs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jacob Wan

unread,
Jan 26, 2014, 4:42:07 PM1/26/14
to sin...@googlegroups.com
Glad to hear it.  Thanks!
Reply all
Reply to author
Forward
0 new messages