Skip to main content

Recording Multiple Behaviors

You can set multiple returning values for the same matching call.

const mockedFoo: Foo = mock(Foo);

when(mockedFoo.getBar(anyNumber())).thenReturn('one').thenReturn('two').thenReturn('three');

const foo: Foo = instance(mockedFoo);

console.log(foo.getBar(1)); // one
console.log(foo.getBar(1)); // two
console.log(foo.getBar(1)); // three
console.log(foo.getBar(1)); // three - last defined behavior will be repeated infinitely

Another example with specific values:

let mockedFoo: Foo = mock(Foo);

when(mockedFoo.getBar(1)).thenReturn('one').thenReturn('another one');
when(mockedFoo.getBar(2)).thenReturn('two');

let foo: Foo = instance(mockedFoo);

console.log(foo.getBar(1)); // one
console.log(foo.getBar(2)); // two
console.log(foo.getBar(1)); // another one
console.log(foo.getBar(1)); // another one - this is last defined behavior for arg '1' so it will be repeated
console.log(foo.getBar(2)); // two
console.log(foo.getBar(2)); // two - this is last defined behavior for arg '2' so it will be repeated

Short notation - you can specify return values as multiple thenReturn args:

const mockedFoo: Foo = mock(Foo);

when(mockedFoo.getBar(anyNumber())).thenReturn('one', 'two', 'three');

const foo: Foo = instance(mockedFoo);

console.log(foo.getBar(1)); // one
console.log(foo.getBar(1)); // two
console.log(foo.getBar(1)); // three
console.log(foo.getBar(1)); // three - last defined behavior will be repeated infinitely

Overlapping matchers

When more than one stub matches the same call, the most recently defined one wins - not the most specific one. This lets you set a default behavior first and override it for specific inputs afterwards:

const mockedFoo: Foo = mock(Foo);

when(mockedFoo.getBar(anyNumber())).thenReturn('default');
when(mockedFoo.getBar(3)).thenReturn('three');

const foo: Foo = instance(mockedFoo);
console.log(foo.getBar(3)); // 'three' - the more recently defined stub wins
console.log(foo.getBar(5)); // 'default' - falls back to the only matching stub

Defining them in the opposite order changes which one wins, since it's always "last defined," not "most specific":

const mockedFoo: Foo = mock(Foo);

when(mockedFoo.getBar(3)).thenReturn('three');
when(mockedFoo.getBar(anyNumber())).thenReturn('default');

const foo: Foo = instance(mockedFoo);
console.log(foo.getBar(3)); // 'default' - defined after the '3'-specific stub, so it wins even for 3