7

I am asking about mock object management, regardless the specific implementation (EasyMock, Mock Object etc).

I have been reluctant to use Mock object in my unit testings, for the following reason: The behavior of Mock object must mirror the behavior of object being mocked. If the behavior of the object being mocked has changed, we will have to change behavior of mock object as well. If we don't, the behavior of mock object will out of sync with the real object, and thus make the unit-testing meaningless, and it's dangerous.

My question are, how to keep the mock object in sync with target object? How do you propagate the changes? Do you use any mock object management technique?

Edit: Change title to narrow down the scope.

janetsmith
  • 8,562
  • 11
  • 58
  • 76

4 Answers4

2

Well defined APIs should not have this sort of leeway: given a set of input, the object being mocked should only behave in these particular ways: the behavior is tied to the interface. If there is allowed variance, then your mock object should be testing all of the different things this object could do.

You can mitigate the risk of behavior drift by:

  • Integration testing, and
  • Comparing your mocked data with the real implementation.
Edward Z. Yang
  • 26,325
  • 16
  • 80
  • 110
0

You're on the right track. You don't want brittle tests that have to be changed every time you refactor the system under test.

In general I concentrate my testing on the public interface. If your public interface changes, you probably have to change more than just tests.

I also try to do state testing instead of behavior testing whenever possible. So I'll usually use stubs instead of mocks. (Most isolation/mocking frameworks will let you create either.) I verify the state of the system (or class) under test rather than asking a mock object to verify itself.

That said, I try to be flexible. If testing mock behavior makes sense in a given case, I'll use that. If I need to expose internals to get decent coverage, I will.

EDIT: See also this article by Scott Bain.

TrueWill
  • 25,132
  • 10
  • 101
  • 150
0

I'm no expert, but my thought on this is that mock object is designed for single test case/interaction. And if that interaction changes, you obviously want that reflected in your tests. But this shouldn't break all mock objects of a class as they check for different interactions which may still be valid.

driushkin
  • 3,531
  • 1
  • 24
  • 25
0

If ClassA calls:

 AThing aThing = ClassB.GiveMeAThing()

ClassA should never care how ClassB gets that thing. Thus, a stub -- StubB -- should never care how a real implementation of the stubbed behaves. Only if the interaction itself changes -- the return type or the calling arguments -- should StubB be changed, and that would be needed if you'd want your code to compile :-)

In the case that your ClassB starts to return Nulls or Throws new types of exceptions; Well, then there are entirely new tests to be written and probably new stubs as well.

Regards, Morten

Morten
  • 3,778
  • 2
  • 25
  • 45