Jasmine spyOn with multiple returns

10.5k views Asked by At

I would like to test my angular application with Jasmine. So I created some tests, most of them work fine. But, one of my functions require the user to fill in an prompt. Tests can not fill this prompt, so I mocked them with spyOn(window,'prompt').and.returnValue('test'). This works, but only once.

When I add two of my components (the function in which the prompt is located), I want to spyOn the first prompt with result 'test', and the second prompt with 'test2'. I tried doing this as follows:

it 'should place the component as last object in the form', ->

      spyOn(window, 'prompt').and.returnValue('test')
      builder.addFormObject 'default', {component: 'test'}

      spyOn(window, 'prompt').and.returnValue('test2')
      builder.addFormObject 'default', {component: 'test2'}

      expect(builder.forms['default'][0].name).toEqual('test')

But this gives the following error: Error: prompt has already been spied upon This is quite logical, but I don't know another way of returning with a spyOn.

So, what I want is this: Before the first addFormObject I want to spy on the prompt which returns 'test'. And the second addFormObject I want to spy with return 'test2'

3

There are 3 answers

0
maurycy On BEST ANSWER

With spyOn you can return mocked value and set it dynamically like in following code

it 'should place the component as last object in the form', ->
  mockedValue = null

      spyOn(window, 'prompt').and.returnValue(mockedValue)
      mockedValue = 'test'
      builder.addFormObject 'default', {component: 'test'}

      mockedValue = 'test2'
      builder.addFormObject 'default', {component: 'test2'}

      expect(builder.forms['default'][0].name).toEqual('test')
1
Max Koretskyi On

But this gives the following error: Error: prompt has already been spied upon

The correct way to do it is like that:

var spy = spyOn(window, 'prompt');

...
spy.and.returnValue('test')

...
spy.and.returnValue('test2')
0
André Werlang On

Since jasmine v2.5, use the global allowRespy() setting.

jasmine.getEnv().allowRespy(true);

You'll be able to call spyOn() multiple times, when you don't want and/or have access to the first spy. Beware it will return the previous spy, if any is already active.

spyOn(window, 'prompt').and.returnValue('test')
...
spyOn(window, 'prompt').and.returnValue('test')