What is the difference between full mocking and partial mocking? - java

I'm currently working with mocking with Mockito using jUnit and I've stumbled upon the Partial Mocking section where you use Mockito.spy to partially mock the object. I don't seem to understand this concept of partial mocking since I can't find a scenario why I should use it (since it's pretty similar to mocking in general).
Can anybody explain how partial mocking differs from the normal mocking? And if possible, kindly provide examples.
Thanks!

Partial mocking is where you take a class and ask it to behave as normal, except you want to override certain functionality.
This is useful for unit testing services who communicate with other parts of your application. By overriding the behaviour that would call the other part of your application you can test your service in isolation.
Another example would be when a component would communicate with a database driver. By mocking the part that would communicate with the driver, you can test that part of the application without having to have a database.

From the EasyMock 2.2 classextension documentation:
Sometimes you may need to mock only some methods of a class and keep
the normal behavior of others. This usually happens when you want to
test a method that calls some others in the same class. So you want to
keep the normal behavior of the tested method and mock the others.
I sometimes use this to mock (complicated or process intensive) private methods that are allready fully tested.
Partial mocking can be very handy, but I try to avoid it as much as possible.

Partial mocking:
Say you have a class which takes 10+ parameters for a constructor (this shouldn't ever happen but for this example lets say it does) it's a real chore to create that entire object. Frameworks like mockito let you just use the parts of the object you really want to test.
for example
#Mock BigClass big; //contains loads of attributes
...
when(big.getAttributeOneOfTwenty()).thenReturn(2); //these are static imports from mockito

I find it useful when I'm forced to work with APIs relying on inheritance from abstract classes and/or legacy code working with nonmockable static classes (one real life example - DAO).
Partial mocking (in sense of using the Spy facility from Mockito) allows you to mock calls to inherited methods in the first case, or wrap calls to static methods you are forced to use into normal methods that you can mock, verify etc.
Generally you should design and write code in such a way, that you won't need this (dependency injection, single responsibility per class etc). But from time to time it's useful.
A quick and rough example, to visualize the static API example:
class BigUglyStaticLegacyApi {
public static Foo someStaticMethodFetchingFoo() {...}
}
class Bar {
public void someMethodYouTest() {
Foo foo = getFoo();
//do something with Foo (a FooBar, for example :) )
}
/*this one you mock via spying - not the most elegant solution,
but it's better than nothing */
#VisibleForTesting
protected Foo getFoo() {
return BigUglyStaticLegacyApi.someStaticMethodFetchingFoo();
}
}

I use it the most to mock some methods in my CUT (Class Under Test) but not the method/s I'm actually unit testing. It is an important feature that should be used in unit testing with Mockito.

Related

Mockito verify that ONLY a expected method was called

I'm working in a Project with a Service class and some sort of a Client that acts as a facade (don't know if it's the right term in the Design Patterns's world, but I'll try to make myself clear). Service's methods can be very expensive as they may be communicating with one or more databases, long checkings and so on, so every Client method should call one and only one Service method.
Service class structure is something like
public class Service {
public void serviceA(){...}
public SomeObject serviceB(){...}
// can grow in the future
}
And Client should be something like
public class Client {
private Service myService; // Injected somehow
public void callServiceA() {
// some preparation
myService.serviceA();
// something else
}
public boolean callServiceB(){...}
}
And in the test class for Client I want to have something like
public class ClientTest{
private Client client; // Injected or instantiated in #Before method
private Service serviceMock = mock(Service.class);
#Test
public void callServiceA_onlyCallsServiceA() {
client.callServiceA();
????
}
}
In the ???? section I want something like verifyOnly(serviceMock).serviceA() saying "verify that serviceMock.serviceA() was called only once and no other method from the Service class was called". Is there something like that in Mockito or in some other mocking library? I don't want to use verify(serviceMock, never()).serviceXXX() for every method because, as I said, Service class may grow in the future and I will have to be adding verification to every test (not a happy task for me) so I need something more general.
Thanks in advance for your answers.
EDIT #1
The difference between this post and the possible duplicate is that the answer adds boiler plate code which is not desired in my case because it's a very big project and I must add as few code as posible.
Also, verifyNoMoreInteractions can be a good option even when it's discouraged for every test, no extra boiler plate code needed.
To sumarize, the possible duplicate didn't solved my problem.
There's another issue: I'm writing test for code made by another team, not following a TDD proccess myself, so my test should be extra defensive, as stated in this article quoted in the mockito documentation for verifyNoMoreInteractions. The methods I'm testing are often very longs so I need to check that the method under test calls ONLY the necesary services and no other (because they're expensive, as I said). Maybe verifyNoMoreInteractions is good enough for now but I'd like to see something not being discouraged for every test by the very same API creator team!
Hope this helps to clarify my point and the problem. Best regards.
verify(serviceMock, times(1)).serviceA();
verifyNoMoreInteractions(serviceMock);
From Mockito's javadoc on verifyNoMoreInteractions:
You can use this method after you verified your mocks - to make sure that nothing else was invoked on your mocks.
Also:
A word of warning: Some users who did a lot of classic, expect-run-verify mocking tend to use verifyNoMoreInteractions() very often, even in every test method. verifyNoMoreInteractions() is not recommended to use in every test method. verifyNoMoreInteractions() is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. Abusing it leads to overspecified, less maintainable tests.
The only way you can reliably verify that your service is only ever called once and only once from the method you specify and not from any other method, is to test every single method and assert that your serviceA method is never invoked. But you're testing every other method anyway, so this shouldn't be that much of a lift...
// In other test cases...
verify(serviceMock, never()).serviceA();
While this is undesirable from a code writing standpoint, it opens the door to separating out your service into smaller, more responsible chunks so that you guarantee that only one specific service is called. From there, your test cases and guarantees around your code become smaller and more ironclad.
I think what you are looking for is the Mockito.verify and Mockito.times
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
verify(mockObject, atLeast(2)).someMethod("was called at least twice");
verify(mockObject, times(3)).someMethod("was called exactly three times");
Here another thread with the same question:
Mockito: How to verify a method was called only once with exact parameters ignoring calls to other methods?

Replay like function in PowerMock-Mockito

Which method in PowerMock-Mockito java can be used to replay the class under test (like PowerMock.replay() followed by PowerMock.verify()) and verify whether the private methods (methods are part of class under test ) calls ?
You shouldn't be verifying private method calls, as they're implementation details. That PowerMock allows you to do so is no indication that you should.
Even if you do choose to mock private method calls, you could only access them from your system-under-test, which indicates that you're mocking the system under test: Don't mock the system under test. It's far too easy to accidentally verify that your mocking system works, not that your component actually does what it's supposed to.
Mockito doesn't have record-replay semantics, so you won't be able to access that functionality from PowerMock-Mockito. You'd need PowerMock's EasyMock syntax instead.

Unit testing and too many mocks

I'm starting to practice TDD in my project, as a background it also contains legacy code. We use Mockito as a mocking framework and follow a Spring MVC approach.
There are times when there's a Service class implemented with many different DAO objects as #Autowired properties. There are simple methods within these services, like for example completeTransaction.
completeTransaction will use many of the DAO objects to complete its responsibilities
Update and save the transaction
Advance a business process
Closing other pending operations
However, in performing those operations, the method requires calls to different DAO to fetch and update the transaction, fetch a business process ID, fetch pending transactions (and save their updates). This means that unit testing this method makes me add many #Mock properties. And I need to set up the mock objects before the test will actually finish for me to test a certain condition.
This seems like a code smell, and to me it almost feels like the test is ensuring the implementation of the code instead of just its contract. Again, without mocking the dependencies, the test case will not run (due to NPE and others).
What is a strategy that I can follow to clean up code like this? (I can't really provide the actual source code on the question though). I'm thinking that one possibility would be to set up a facade class with methods like ("getPendingOperations" and "advanceBusinessProcess"). Then I can mock a single dependency. But then I figure that in all other classes that have situations like this I would need to do the same, and then I'm afraid to end up with a lot of "helper" classes just for the sake of cleaner tests.
Thank you in advanced.
I think you'll want to do two things in general when you find yourself with too many mocks. These are not necessary easy, but you may find them helpful.
1) Try and make your methods and classes smaller. I think Clean Code says there are two rules, that classes should small. And that classes should be smaller then that. This makes some sense because as the units you are testing (methods and classes) get smaller, so will the dependencies. You will of course end up with more tests, but they will have less setup in each test.
2) Look at the Law of Demeter (https://en.wikipedia.org/wiki/Law_of_Demeter). There are a bunch of rules, but basically, you want to avoid long string of property/method calls. objA = objB.propertyA.SomeMethod().propertyC; If you need to mock out all of these objects just to get objA, the you will have a lot of setup. But if you can replace this with objA = objB.newProperty; then you only need to mock objB and it's one property.
Neither of these are silver bullets, but hopefully you can use some of these ideas with your project.
If the unit test is testing the completeTransaction method, then you must mock everything on which it depends. Since you are using Mockito, you can use verify to confirm that the correct mocked methods are called and that they are called in the correct order.
If the unit test is testing something that calls the completeTransaction method, then just mock the completeTransaction method.
If this is your class hierarchy:
class A -> class B -> class C
(where -> is "depends on")
In unit tests for class A, mock only class B.
In unit tests for class B, mock only class C.

How to test "add" in DAO without using "find" etc.?

In following code the issue is, that I cannot test dao.add() without using dao.list().size() and vice versa.
Is this approach normal or incorrect? If incorrect, how can it be improved?
public class ItemDaoTest {
// dao to test
#Autowired private ItemDao dao;
#Test
public void testAdd() {
// issue -> testing ADD but using LIST
int oldSize = dao.list().size();
dao.add(new Item("stuff"));
assertTrue (oldSize < dao.list().size());
}
#Test
public void testFind() {
// issue -> testing FIND but using ADD
Item item = new Item("stuff")
dao.add(item);
assertEquals(item, dao.find(item.getId()));
}
}
I think your test are valid integration tests as stated above, but I would use Add to aid in the testing of of Find and vice verse..
At some level you have to allow yourself to place trust in your lowest level of integration to your external dependency. I realize there is a dependency to other methods in your tests, but I find that Add and Find methods are "low level" methods that are very easy to verify.
They essentially test each other as they are basically inverse methods.
Add can easily build preconditions for find
Find can verify that an add was successful.
I can't think of a scenario where a failure in either wouldn't be caught by your test
Your testAdd method has a problem: it depends on the assumption that ItemDao.list functions properly, and yet ItemDao is the Class that you're testing. Unit tests are meant to be independent, so a better approach is use plain JDBC -as #Amir said- to verify if the record was introduced in the database.
If you're using Spring, you can relay on AbstractTransactionalDataSourceSpringContextTests to access JDBCTemplate facilities and assure a rollback after the test was executed.
I use direct JDBC (using Spring's JdbcTemplate) to test the DAO methods. I mean I call the DAO methods (which are Hibernate base), and then confirm them using JDBC direct SQL calls.
The smallest unit under test for class-based unit testing is a class.
To see why, consider that you could, in theory, test each method of the class in isolation from all other methods by bypassing, stubbing or mocking them. Some tools may not support that; this is theory not practice, assume they do.
Even so, doing things that way would be a bad idea. The specification of an individual function by itself will vary between vaguely meaningless and verbosely incomprehensible. Only in the pattern of interaction between different functions will there exist a specification simpler than the code that you can profitably use to test it.
If you add an item and the number of items reported increases, things are working. If there is some way things could not be working, but nevertheless all the patterns of interaction hold, then you are missing some needed test.

Is there a better way to test the following methods without mocks returning mocks?

Assume the following setup:
interface Entity {}
interface Context {
Result add(Entity entity);
}
interface Result {
Context newContext();
SpecificResult specificResult();
}
class Runner {
SpecificResult actOn(Entity entity, Context context) {
return context.add(entity).specificResult();
}
}
I want to see that the actOn method simply adds the entity to the context and returns the specificResult. The way I'm testing this right now is the following (using Mockito)
#Test
public void testActOn() {
Entity entity = mock(Entity.class);
Context context = mock(Context.class);
Result result = mock(Result.class);
SpecificResult specificResult = mock(SpecificResult.class);
when(context.add(entity)).thenReturn(result);
when(result.specificResult()).thenReturn(specificResult);
Assert.assertTrue(new Runner().actOn(entity,context) == specificResult);
}
However this seems horribly white box, with mocks returning mocks. What am I doing wrong, and does anybody have a good "best practices" text they can point me to?
Since people requested more context, the original problem is an abstraction of a DFS, in which the Context collects the graph elements and calculates results, which are collated and returned. The actOn is actually the action at the leaves.
It depends of what and how much you want your code to be tested. As you mentionned the tdd tag, I suppose you wrote your test contracts before any actual production code.
So in your contract what do you want to test on the actOn method:
That it returns a SpecificResult given both a Context and an Entity
That add(), specificResult() interactions happen on respectively the Context and the Entity
That the SpecificResult is the same instance returned by the Result
etc.
Depending on what you want to be tested you will write the corresponding tests. You might want to consider relaxing your testing approach if this section of code is not critical. And the opposite if this section can trigger the end of the world as we know it.
Generally speaking whitebox tests are brittle, usually verbose and not expressive, and difficult to refactor. But they are well suited for critical sections that are not supposed to change a lot and by neophytes.
In your case having a mock that returns a mock does look like a whitebox test. But then again if you want to ensure this behavior in the production code this is ok.
Mockito can help you with deep stubs.
Context context = mock(Context.class, RETURNS_DEEP_STUBS);
given(context.add(any(Entity.class)).specificResult()).willReturn(someSpecificResult);
But don't get used to it as it is usually considered bad practice and a test smell.
Other remarks :
Your test method name is not precise enough testActOn does tell the reader what behavior your are testing. Usually tdd practitioners replace the name of the method by a contract sentence like returns_a_SpecificResult_given_both_a_Context_and_an_Entity which is clearly more readable and give the practitioner the scope of what is being tested.
You are creating mock instances in the test with Mockito.mock() syntax, if you have several tests like that I would recommend you to use a MockitoJUnitRunner with the #Mock annotations, this will unclutter a bit your code, and allow the reader to better see what's going on in this particular test.
Use the BDD (Behavior Driven Dev) or the AAA (Arrange Act Assert) approach.
For example:
#Test public void invoke_add_then_specificResult_on_call_actOn() {
// given
... prepare the stubs, the object values here
// when
... call your production code
// then
... assertions and verifications there
}
All in all, as Eric Evans told me Context is king, you shall take decisions with this context in mind. But you really should stick to best practice as much as possible.
There's many reading on test here and there, Martin Fowler has very good articles on this matter, James Carr compiled a list of test anti-patterns, there's also many reading on using well the mocks (for example the don't mock types you don't own mojo), Nat Pryce is the co-author of Growing Object Oriented Software Guided by Tests which is in my opinion a must read, plus you have google ;)
Consider using fakes instead of mocks. It's not really clear what the classes in question are meant to to, but if you can build a simple in-memory (not thread-safe, not persistent etc) implementation of both interfaces, you can use that for flexible testing without the brittleness that sometimes comes from mocking.
I like to use names beginning mock for all my mock objects. Also, I would replace
when(result.specificResult()).thenReturn(specificResult);
Assert.assertTrue(new Runner().actOn(entity,context) == specificResult);
with
Runner toTest = new Runner();
toTest.actOn( mockEntity, mockContext );
verify( mockResult ).specificResult();
because all you're trying to assert is that specificResult() gets run on the right mock object. Whereas your original assert doesn't make it quite so clear what is being asserted. So you don't actually need a mock for SpecificResult. That cuts you down to just one when call, which seems to me to be about right for this kind of test.
But yes, this does seem frightfully white box. Is Runner a public class, or some hidden implementation detail of a higher level process? If it's the latter, then you probably want to write tests around the behaviour at the higher level; rather than probing implementation details.
Not knowing much about the context of the code, I would suggest that Context and Result are likely simple data objects with very little behavior. You could use a Fake as suggested in another answer or, if you have access to the implementations of those interfaces and construction is simple, I'd just use the real objects in lieu of Fakes or Mocks.
Although the context would provide more information, I don't see any problems with your testing methodology myself. The whole point of mock objects is to verify calling behavior without having to instantiate the implementations. Creating stub objects or using actual implementing classes just seems unnecessary to me.
However this seems horribly white box, with mocks returning mocks.
This may be more about the class design than the testing. If that is the way the Runner class works with the external interfaces then I don't see any problem with having the test simulate that behavior.
First off, since nobody's mentioned it, Mockito supports chaining so you can just do:
when(context.add(entity).specificResult()).thenReturn(specificResult);
(and see Brice's comment for how to do enable this; sorry I missed it out!)
Secondly, it comes with a warning saying "Don't do this except for legacy code." You're right about the mock-returning-mock being a bit strange. It's OK to do white-box mocking generally because you're really saying, "My class ought to collaborate with a helper like <this>", but in this case it's collaborating across two different classes, coupling them together.
It's not clear why the Runner needs to get the SpecificResult, as opposed to whatever other result comes out of context.add(entity), so I'm going to make a guess: the Result contains a result with some messages or other information and you just want to know whether it's a success or failure.
That's like me saying, "Don't tell me all about my shopping order, just tell me that I made it successfully!" The Runner shouldn't know that you only want that specific result; it should just return everything that came out, the same way that Amazon shows you your total, postage and all the things you bought, even if you've shopped there lots and are perfectly aware of what you're getting.
If some classes regularly use your Runner just to get a specific result while others require more feedback then I'd make two methods to do it, maybe called something like add and addWithFeedback, the same way that Amazon let you do one-click shopping by a different route.
However, be pragmatic. If it's readable the way you've done it and everyone understands it, use Mockito to chain them and call it a day. You can change it later if you have need.

Categories

Resources