Changing Final field using mockito - java

I have a problem with mockito while mocking up the final field of a class can you guys help on that
public class Product{
public final String VALUE= "ABC";
public String someMethod(){
if (!VALUE.equals("ABC")){ ## IF NOT WORKING
//inside if condition
}else{
//inside else condition
}
}
}
//Test Class
#test
public void test_someMethod(){
Product product = Mockito.mock(Product.class,"Product");
Field field = Product.class.getDeclaredField("VALUE");
field.setAccessible(true);
ReflectionUtils.setField(field, product , "XYZ");
}
Now, when running in debug mode this shows me changed value to XYZ but dosen't work with if condition always goes in else block despite shows XYZ in debug mode.

Basically, you are going down the very wrong rabbit hole here. It is not a good idea to throw together so many things.
First of all, Mockito (and all the other mocking frameworks) are intended to be used for behavior, not state. In other words. Albeit your mock object actually has that field, keep in mind: it still is a mock object. You won't find much documentation or tutorials telling you what the mocking framework will do about fields, and field values of mocked objects.
Worse, and the real problem: you do not mock your class under test. You use mocks to gain control over other objects that your code under test is using. Mocking and testing the same object simply does not make (much) sense!
Then: do not use reflection together with "mocking" based unit testing, especially not to "reflect" on mocked objects. As said: these frameworks do whatever they think is necessary, so even if some code works today, there is a realistic chance that a new version of Mockito might change such internals, and cause such code to fail in the future.
Next, note that your code is nonsensical to begin with:
public final String VALUE= "ABC";
public String someMethod(){
if (!VALUE.equals("ABC")){ ## IF NOT WORKING
VALUE is always ABC, so you always end up with if(!true). There is no point in having that if statement in your code then.
So, if you really need such kind of a switch, you could make it a method call, like:
public String someMethod(){
if (reallyDoIt())) ...
with
boolean reallyDoIt() { return ...
The point is: now you could use Mockito's spy concept to test your someMethod() call. By doing so, you can instruct Mockito to "really" call someMethod() but to return a fake answer for reallyDoIt(). For more details, see here for example.
Beyond that, I strongly recommend that you step back and read a good tutorial about Mockito, like the one from vogella. Simply because your code implies that you do not really understand how to use mocking frameworks in unit testing.

Thanks.. for detailed explanation. But for me here limitation is not to change the base code (I.e somemethod()).

Related

Junit skip call to a function into another question

I want to test a function in my code. This function calls another function in the same class but in my test I don't want to call it (I don't need it). Somehow, my test always goes into that inner function and makes errors. Is there any means to "skip" the call to that inner function ?
Here's an example :
void function1() {
if(condition == true) {
variable1 = function2()
}
}
Object function2() {
//Do something
return Object;
}
Is there a way to avoid calling function 2 ?
Thank you.
First you should consider fixing those errors thrown from function2().
If however you want to test the function1() isolated then the behavior you are describing is called Test Doubles. One kind of those test doubles is Mocking where you can drive the behavior of a class or a method.
There are frameworks doing this such as Mockito, but of course you can solve that problem on your own not depending on frameworks.
For example if you use Mockito you should end up mocking the function2() method like this
YouClassName mockedClass = mock(YouClassName.class);
when(mockedClass.function2()).thenReturn(new Object()); //you can of course return anything here
Its pretty common to test functions in isolation but in times where are dependencies between objects. If there are no dependencies you should probably consider not using test doubles (unless you are sure what you are doing).
Frameworks such as Mockito offer concepts such as spies. Using a Mockito spy, you can gain full control over which methods get invoked.
But: you only do that for very specific cases.
When you have a hard time testing your production code, then most likely: because you have written hard to test code.
Thus: you could try to use a spy here, but I would rather advice to step back and re-think what exactly you intend to do here.

Unit testing in java using mockito and powermockito

I have a method
public TaskProperty addTask()
{
/*some operations
*
*/
mapToProperty();
}
private TaskProperty mapToProperty()
{
/**some op's**/
}
How to write unit test case for the addTask() without allowing the control to go inside mapToProperty() method.
How to mock the private method mapToProperty()?
The fact that you want to do this ... doesn't make it a good idea:
private methods represent "internal implementation" details. Excluding them from a test ... means that your test needs to know about this private method. But your tests shouldn't know anything about your private implementation details. They should not need to care.
In other words: your unit tests should only care about the public interface of your class(es). Thus: you try to write all your code in a way that you can test those public methods without the need to "disable" something other in the class you are testing. Meaning: either try to rewrite your private method so that you can call it from any unit test; or if that is not possible, move the corresponding behavior into another class; and then provide a mocked instance of that class to your method under test.
Long story short: your question implies that you want to fix a "bad design" by using the "mocking framework hammer" to "massage" the symptom. But it a symptom; and the underlying problem is still there, and affects your code base. So spend your time fixing the real problem; instead of working around it!
And just in case you still prefer to mock that private method; I would rather suggest to look into a mockito spy to do that (although PowerMock also allows for such kind of test, see here)

When to use when() in Mocktio

I am writing unit tests with JUnit and Mockito. Let's say I have following test class:
#Mock(name="myService")
private myServiceClass myService;
#InjectMocks
private myClassIWantToTest classUnderTest;
final myModelClass myModel = new myModelClass();
#Before
private void setUp(){
MockitoAnnotiations.initMocks(this);
}
#Test
private void testSomething(){
myModel.setCode("someCode");
final MyDataClass myData = new MyDataClass();
myData.setCode("someCode");
doReturn("someCode").when(myModel.getCode());
doReturn(myModel).when(myService.getModelByCode("someCode"));
assertEquals(classUnderTest.getDataByCode(eq("someCode")), myData);
verify(myService.getModelByCode(eq("someCode")), atLeastOnce());
}
The method getDataByCode from my classUnderTest converts the Model into Data and it should have the same code. What is a bit blurry to me is that unit tests should encapsule the classUnderTest from all dependencies. But now I have a problem. I use the setter methods myData and myModel to set a value. The thing is I put a DoReturn in there for myModel, but the problem is, that it's not a injected Mock. The method I try to test unfortunately doesn't have a field, it initializes this inside the method, so I can't really address it.
And the main thing is, when the setter of for example myModel doesn't work anymore or so, my test as shown above, wouldn't work anymore. I guess I have three questions:
How hard do I need to isolate the test class? Don't I need to use the setters for the assertEquals?
Is there another way to deal with objects, which are initialized inside a method I want to test? What is the best way to approach such a matter?
Also, what would be a good pattern for structuring this? I currently initialize my expected myData result inside a test method. The thing is that this is a rather short and easy example, but I have classes where I have tons of objects and methods.
Sounds like your main problem is the design of the class you want to test. But a few things before:
myModel.setCode("someCode");
doReturn("someCode").when(myModel.getCode());
This doesn't make sense. It's not a mock, so do...when doesn't make sense here. And if it was a mock, calling the setter would be useless.
assertEquals(classUnderTest.getDataByCode(eq("someCode")), myData);
Also strange. You want to call getDataByCode, why the eq? Do it. Call it. Write:
assertEquals(classUnderTest.getDataByCode("someCode"), myData);
Mockito-Matchers are good when you want to verify something but normally you don't use them as parameters for real method calls.
verify(myService.getModelByCode(eq("someCode")), atLeastOnce());
Does this code really compile? Shouldn't it be ...
verify(myService, atLeastOnce()).getModelByCode(eq("someCode"));
So, it would be a good idea to actually isolate your unit tests as far as you can. The less external problems you are inviting into your test, the better the test can be.
The method I try to test unfortunately doesn't have a field, it
initializes this inside the method, so I can't really address it.
This simply sounds like a code smell, but without the actual code in question, it's hard to say...

Mockito Spy'ing on the object being unit tested

Is it a code smell to spy on an object that is being unit tested? For example say I have a LineCounter class whose job is to simply count the number of lines in a string. --
class LineCounter {
public int getNumLines(String string) {
String metadata = getStringMetadata(string);
// count lines in file
return numLines;
}
/** Expensive operation */
protected String getStringMetadata(String string) {
// do stuff with string
}
}
Now I want to write a JUnit 4 test for this to test the getNumLines method while mocking out the expensive getStringMetadata call. I decide to use Mockito's spy mechanism to have getStringMetadata return a dummy value.
class LineCounterTests {
#Test public void testGetNumLines() {
LineCounter lineCounterSpy = Mockito.spy(new LineCounter());
// Mock out expensive call to return dummy value.
Mockito.when(lineCounterSpy.getStringMetadata(Mockito.anyString()).thenReturn("foo");
assertEquals(2, lineCounterSpy.getNumLines("hello\nworld");
}
}
Is this a reasonable thing to do? I feel pretty weird testing a Spy object rather than the actual class, but I can't really think of a reason against it.
I will answer the question in two parts. First, yes it is code smell to mock or spy the class under test. That does not mean that it cannot be done correctly but that it is risk prone and should be avoided whenever possible.
WRT your specific example, I would see how the spy could be correctly used but that would be predicated on the assertion that you have elsewhere fully unit tested getStringMetadata. This then begs the question, if you have fully unit tested getStringMetadata elsewhere then you must know how to test it and therefore why not test getNumLines without the spy.
All this being said, millhouse makes a good point but either way you have to unit test the expensive code somewhere. His suggestion goes a long way to help isolate the expensive code and ensure that you only have to test / exercise it once.
In this situation, it is perfectly legitimate to stub the method that is called by the method under test. It is even the only way I can think of to test it in isolation. You just don't want to extract a single method into it's own class for the sole purpose of testing.
Beware of the side effects in the stubbed method though. It might not be sufficient to stub the returned value, if the stubbed method has side effects then you have to stub the side effects as well. It might even be a reason against it in some situations where the side effects are very complex, but that would most likely be an indication of a code smell in the implementation of the class under test itself.
To answer your question, I find it easy to find reasons for it, but hard to find reasons against it. It's the technique I use every day, it helps me split my implementation in small methods that are tested individually in complete isolation, and I haven't seen any limitation to it yet.

unit test best practice for method with mocks in Mockito

Lets say we have method to test in class A that calls method from class B. To test it we created mock for B and then verify if it was called. Is verify(...) enough for unit test or I need assert actual result of tested method?
Below is simplified example to clarify my concern:
public class StringWriterATest {
StringWriterB b = mock(StringWriterB.class);
#Test
public void stringWriterATest() {
StringBuffer sb = new StringBuffer();
StringWriterA a = new StringWriterA();
a.stringWriterB=b;
a.append(sb);
ArgumentCaptor<StringBuffer> argument = ArgumentCaptor.forClass(StringBuffer.class);
verify(b).append(argument.capture());
assertEquals("StringWriterA", ((StringBuffer)argument.getValue()).toString());
//do we really need this or above is enough for proper unit test of method a.append(sb);
//assertEquals("StringWriterA_StringWriterB", sb);
}
}
public class StringWriterA {
public StringWriterB stringWriterB;
public void append(StringBuffer sb) {
sb.append("StringWriterA");
stringWriterB.append(sb);
}
}
class StringWriterB {
public void append(StringBuffer sb) {
sb.append("StringWriterB");
}
}
Regards,
Max
There is never a need to mock a return value and verify an object at the same time.
Consider this:
StringWriterA is the class under test. Therefore you'll definitely want to use assertions to verify the behavior of this class. In order to do this, you mock out a dependency, StringWriterB.
You do not want to test StringWriterB in your test of StringWriterA, therefore any assertions of StringWriterB interactions in your test are in the wrong place.
You must assume that StringWriterB is behaving as expected. You either want to verify that StringWriterA called StringWriterB correctly (using verify()) or you want to mock its expected behavior and mock the return values.
If you mock, then the verify is implicit since the mocked return value will not be returned if the method is not called.
In your case, StringWriterA.append() does not return any value, so only a verify is even possible. That StringWriterB.append() also works should have a similar verify test in a stringWriterBTest of its own.
Note: It's nice to be explicit with tests. Since test methods are never called outside of a framework, there is never a need to type them out, so you can have much longer method names than in production code methods. A nice convention is:
<underTest>Should<Expected>[When]<Condition>()
i.e.
stringWriterAShouldAppendConstantAndDelegateToStringWriterB()
stringWriterAShouldThrowNullPointerExceptionWhenNullArgument()
When you have test failures in your build (continuous integration), then you don't have to hunt down what went wrong, the method name appears right by the failure and you can read it to know exactly what behavior must be fixed.
In your example, StringWriterB stores no state and the append method could easily be static. In that case then the call is purely a side effect and does not need to be tested.
However, I suspect your real code is much more complex. If there is a of another object accessing StringWriterB then you maye want to mock it out in case there are unexpected calls to it. You also may want to add the verify of B if you expect it to be expanded in the future -- possibly storing state from the append call and having accessors.
One thing to consider is what the purpose of the call to StringWriterA.append() is. If it's job is to append the string StringWriterAStringWriterB then that is what you should be testing and a mock is not necessary. How StringWriterA accomplishes that task is immaterial. If, however, part of its job is to also call the StringWriterB.append() method then a mock may will be necessary unless you want to test StringWriterB in A's test.
My rule of thumb WRT mocks is to use real objects until the wiring for the objects I'm not directly testing gets too hairy or too brittle. If I feel like a good portion of my tests are in actuality testing other objects then mocks would be a good idea.
First of all try to show somebody the test you wrote. It is hard to read in my opinion. You can't really tell from it what behaviour you are testing. A brief intro for you how to make it a bit more readable can be found here How to Write Clean, Testable Code .
Using argument captors is also a smell. Some examples how to avoid it can be found on this tdd blog.
To answer you question, verify is used to verify interactions between classes. It is used to drive the design of your code. The result (if needed) should be specified by a when or given at the beginning of your test.
Further information how to drive your design with mocks (when, given, verify, ...) and how mocks are different to stubs can be found here: Mocks are not stubs. That example uses JMock not Mockito for defining mocks, but it is very similar (it is about the concepts, not the details of implementation and libraries you use).

Categories

Resources