How to keep a Mock object in sync with the target

I ask about the management of a simulated object, regardless of the specific implementation (EasyMock, Mock Object, etc.).

I did not want to use the Mock object in my unit tests for the following reason: The behavior of the Mock object should reflect the behavior of the mocked object. If the behavior of the tricked object has changed, we will also have to change the behavior of the layout. If we do not, the behavior of the mock object will be incompatible with the real object and, thus, will make unit testing pointless and dangerous.

My question is: how to keep the layout of the object in sync with the target? How do you spread the change? Do you use any mock object management technique?

Edit: Change the title to narrow the scope.

+4
source share
4 answers

Well-defined APIs should not have this approach: if a set of input data is specified, an object that mocks it should behave only in such ways: the behavior is tied to the interface. If variance is allowed, then your layout should test all the things that this object can do.

You can reduce the risk of behavior drift:

  • Integration testing and
  • Comparison of your mocking data with real implementation.
+2
source

You are on the right track. You do not want fragile tests to be changed every time you reorganize the system under test.

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

I also try to do state testing instead of checking behavior when possible. Therefore, I usually use stubs instead of mocks . (Most isolation / mocking frameworks will allow you to create one.) I check the state of the system (or class) under test, and do not request that the mock object check itself.

However, I try to be flexible. If testing fraudulent behavior makes sense in this case, I will use it. If I need to expose the insides to get decent coverage, I will.

EDIT . See also the article by Scott Ben .

0
source

I am not an expert, but my thought about this is that the layout of the object is for one test case / interaction. And if this interaction changes, you obviously want it to be reflected in your tests. But this should not destroy all layouts of class objects, since they check for different interactions that may be valid.

0
source

If ClassA calls:

AThing aThing = ClassB.GiveMeAThing() 

ClassA does not have to care about how ClassB gets this thing. Thus, the stub - StubB - should not care about how the actual implementation of the stub behavior behaves. Only if the interaction itself is changed - return type or calling arguments - should StubB be changed, and this would be necessary if you wanted your code to compile :-)

In the event that your ClassB starts to return Nulls or throws new types of exceptions; Well, then there are completely new tests that need to be written and, possibly, new stubs.

Regards, Morten

0
source

Source: https://habr.com/ru/post/1342568/


All Articles