How to override or remove methods from a Flexmock mock object | BlueDiapente - Lilibeth De La Cruz

BlueDiapente

How to override or remove methods from a Flexmock mock object

One issue I've had with Flexmock is that sometimes I wish I could override previous method expectations. Let's see this for example:

bird = flexmock('bird')
bird.should_receive(:sing).and_return('first song')
puts bird.sing # "first song"

bird.should_receive(:sing).and_return('second song')
puts bird.sing # "first song"

One would think that the second call to the sing method would return "second song" but it doesn't. It returns "first song" because once you set up expectations for a mock object, you can't override them.

You can work around it if you first define one an expectation as the "default". Then you can define a different, more specific one.

bird = flexmock('bird')
bird.should_receive(:sing).and_return('first song').by_default
puts bird.sing # "first song"

bird.should_receive(:sing).and_return('second song')
puts bird.sing # "second song"

What if you want to do something like this?

vowels = ['a', 'e', 'i', 'o', 'u']
bird = flexmock('bird')

vowels.each do |vowel|
    bird.should_receive(:sing).and_return(vowel*3)
    puts bird.sing
end

This will output:

aaa
aaa
aaa
aaa
aaa

This is because the expectation is set to return 'a' the first time and then it cannot be overriden.

What I do to solve this, especially if I don't have many more expectations for that mock object, is to simply finalize the mock object. This way you could do something like this:

vowels = ['a', 'e', 'i', 'o', 'u']
vowels.each do |vowel|
    bird.flexmock_teardown
    bird = flexmock('bird')

    bird.should_receive(:sing).and_return(vowel*3)
    puts bird.sing
end

This would output:

aaa
eee
iii
ooo
uuu

The key parts here are bird.flexmock_teardown which tears down the mock object and bird = flexmock('bird') which initializes the mock object after each teardown. Keep in mind that all expectations will be lost each time you call the flexmock_teardown method, and they will need to be established again as necessary.