-1

TDD and general best practices around writing tests say that we should test the behavior and not implementation.

Hypothesis:

In that context, EasyMock.expect().andReturn() should never be used because expect().andReturn() will fail if the expected method is not called on the mocked object.

Instead, expect().andStubReturn() should be used.

Is this hypothesis correct?

I am viewing "testing implementation" as a guard rail against bad programmers who just push code without proper testing. Is that a bad practice?

kaiser
  • 11
  • 4
    I'm having a hard time following this, can you [edit] to clarify what you are asking? – enderland Feb 11 '17 at 03:31
  • Sorry. Edited the question for clarity. Its pending peer review. EasyMock.expect().andReturn() will fail if expected method is not called. If we just want to mocked object to return a value, we can use expect().andStubReturn() instead of .return() as .stubReturn() will not fail if the expected method is not called. Does that imply that we are testing the implementation and not the actual behavior by calling EasyMock.expect().andReturn()? – kaiser Feb 12 '17 at 04:58

2 Answers2

2

Mocking interactions between an object and its public collaborators is not testing implementation, it is testing the observable behaviour of the object. Only if the object you are supplying a mock implementation of is an internal implementation detail of the object you are testing would using a mock amount to testing the implementation.

Using mock objects is a common (albeit not entirely necessary) feature of TDD. Use them whenever the public interactions between objects are important.

Jules
  • 17,614
  • 2
  • 33
  • 63
-1

Testing behavior is ideal cause your tests will become less fragile against future code changes. When you change the 'how' and not the 'what', you'd prefer most of your test to keep functioning.

Invoking or sending a message to some other component can be part of the 'what' and does not mean you are therefor testing implementation.

Having said that you should not stop sometimes dropping down to implementation details if it helps you to gain comfort in your code. Your TDD cycle is really more important, sometime you use it to drive out the implementation with an overarching 'red' behavioral test. This is especially valuable with more complicated algorithms, you not only test the end result but also concrete intermediate -implementation- steps to make sure you did it right.

Joppe
  • 4,548
  • 17
  • 25
  • Thanks for the down vote, care to explain? – Joppe Feb 11 '17 at 17:33
  • If you feel a need to test internals, there's likely a class begging to be extracted. Listen to what your tests are telling you. – RubberDuck Feb 12 '17 at 02:05
  • @rubberduck That's not what I meant. For example if you are to implement a dijkstra search algorithm, will you only test for the expected shortest route or will you test some of the components of the algorithm also? – Joppe Feb 12 '17 at 16:00