2

(I will show examples using php and phpunit but this may be applied to any programming language)

The case: let's say we have a method A::foo that delegates some work to class M and returns the value as-is.

Which of these solutions would you choose:

$mock = $this->getMock('M');
$mock->expects($this->once())
     ->method('bar')
     ->will($this->returnValue('baz'));

$obj = new A($mock);

$this->assertEquals('baz', $obj->foo());

or

$mock = $this->getMock('M');
$mock->expects($this->once())
     ->method('bar')
     ->will($this->returnValue($result = 'baz'));

$obj = new A($mock);

$this->assertEquals($result, $obj->foo());

or

$result = 'baz';
$mock = $this->getMock('M');
$mock->expects($this->once())
     ->method('bar')
     ->will($this->returnValue($result));

$obj = new A($mock);

$this->assertEquals($result, $obj->foo());

Personally I always follow the 2nd solution, but just 10 minutes ago I had a conversation with couple of developers who said that it is "too tricky" and chose 3rd or 1st.

So what would you usually do? And do you have any conventions to follow in such cases?

5

I would choose 3rd solution for two reasons:

  1. Having it defined as $result = ... makes it possible to assign a different value to $result later.

  2. Precisely because second method is too tricky. I think its important for code to be readable and understandable by others as much as possible without comments.

  • "makes it possible to assign a different value to $result later." --- 2nd allows that as well – zerkms Jun 7 '12 at 10:47
  • sorry there was a problem when I submitted the answer earlier. now I have edited it. – Ozair Kafray Jun 7 '12 at 10:56
  • +1 for point number two. A test method should be simple and easy to follow. Being clever and saving yourself one line of code is not worth it if it makes things harder to follow. – unholysampler Jun 7 '12 at 12:11
  • 1
    much easier to assign a value to $result in the debugger with the third method. – user53019 Jun 7 '12 at 17:09
2

IMHO all the 3 approaches are fine
considering all three cases
1. You return a value ('baz') and then apply the assertion using the same value.
2. You are returning a variable which you are assigning while returning the same.
3. You have a previously assigned variable ($result ='baz') which you return and then use the same variable for the assertion.

Your 2nd strategy is a bit tricky because you assign the variable value during return time.
Considering in general case if my function fails to execute.Then trying to use $result variable anywhere else besides the assertion makes no sense since it is unassigned.
Whereas in the other 2 cases I can use the value('baz') directly or use the varable $result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.