Fake test object method

Is there a reason why you shouldn't create a partial fake of an object or just fake one method of the object that you are testing it to test another method? This can be useful in order to save you from creating an entire new mock object, or when there is an external dependency in a method that you pretend that you cannot reasonably get rid of, and would like to avoid all other unit tests?

+6
source share
5 answers

The retrieval and redefinition method described in Chapter 3 by Roy Oscherov. The art of unit testing seems to be a way to fake part of the test class (pp. 71-77). Osherove does not address the issues raised in some other answers to this question.

In addition, Michael Perce discusses this in Efficient Code Management. It expresses the resulting class with a subclass of testing (227) and the method Subclass and Override Method (401). Now, provided, Feathers does not provide a summary of the pristine methods recommended by the new code. But he still takes her seriously as a potentially useful technique.

I also asked my former computer professor about this. It reads well and currently works full time in the software industry, where it is developing rapidly. He said that this technique certainly has a good use, and that there are several dozen classes in his company that pass the test in this way. He said that, like any technique, this can be excessive.

I originally wrote the question when I was new to unit testing and knew almost nothing about dependency injection. Now, after some experience with both, I would add that the need to use this testing technique can be an odor. This may be a sign of the need to redesign your dependency approach. If the method that you want to fake is the one that is inherited from the base class, this may mean that you need to be more serious about honoring "composition preference over inheritance." You should enter your dependencies, not inherit them.

+1
source

The objects you want to do for this are trying to do too many things. In particular, if you have an external dependency, you usually create an object to isolate this dependency. The Facade template is one example of this. If your objects were not designed with verification capabilities, you may have to do some refactoring. Take a look at the Michael Feathers Legacy Code PDF File (PDF). He also has a book of the same name, which goes in much more detail.

+3
source

It is a very bad idea to falsify / fake part of a class to test another.

By doing this, you do not check what the real code does under test conditions, which leads to unreliable test results.

It also increases the load on the content of the fake part of the class. If this applies to the entire test program, the fake implementation also makes other tests on the fake method more complex.

You need to ask yourself why you need to fake the tested part.

If this is because the method is accessing a file or database, then you must define an interface and pass an instance of that interface to the constructor or class method. This allows you to test different scenarios in the same test application.

If this is because you use singles, you need to rethink your design to make it more verifiable: removing singlets will remove implicit dependencies and nightmares for maintenance.

If you use static methods / stand-alone functions to access data in the registry or settings file, you should really transfer this from the function being tested and pass the data as a parameter or provide the interface of the settings provider. This will make the code more flexible and reliable.

If it should break the dependency for testing purposes (for example, faking a vector method to test a method in a matrix class), then you should not fake it - you should consider the test code as defined by the test class with its open interface: methods; preconditions, post-conditions, invariants, documentation, parameters and exception specifications.

You can use implementation details to check for special cases of edges, but run them through the main API, rather than falsifying implementation details.

For example, suppose you are fake std :: vector :: at (), but the implementation has switched to using the [] operator. Your test will be interrupted or silently pass.

+2
source

If the method you want to fake is virtual (for example, not static and not final), then you can subclass your object in your test, override the method in a subclass, and subclass in the test. No mock object libraries are required.

(Ideally, you should consider refactoring, this is not a very long solution, but it is a way to get outdated code for the test so that you can easily start the refactoring process.)

+1
source

There are some really good packages to facilitate this kind of thing. For example, from Mockito Docs :

//You can mock concrete classes, not only interfaces LinkedList mockedList = mock(LinkedList.class); //stubbing when(mockedList.get(0)).thenReturn("first"); 

there is some real magic that is hard to believe at first. When you call

 String firstMember = mockedList.get(0); 

you will return β€œfirst” because of what you said in the β€œwhen” instruction.

0
source

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


All Articles