I am using powermock.
I am facing issues with below scenario.
UPDATE:
My Question is different.
The example given in another link, has private method returning some value.
Here in my case both the methods are returning Void.
class ClassForWhichTestCasesIsPrepared {
private void myPrivateMethod(String param1, MyBean param2) {
//Some Code Here to save data
}
public void myPublicMethod() {
//Some Code Here to find the require paramters to pass to below method
myPrivateMethod(String param1, MyBean param2);
}
}
Facing Issues for Writing Test Cases for myPublicMethod to Mock the private method in same class.
I want to mock the myPrivateMethod method, as it should not be called but myPublicMethod should be covered for test cases.
Both the methods are void.
I cannot change this design, I just have to complete and cover the required test cases for same.
You can use spy method provided by PowerMock.
e.g.
ClassForWhichTestCasesIsPrepared spy = PowerMockito.spy(new ClassForWhichTestCasesIsPrepared());
when(spy, method(ClassForWhichTestCasesIsPrepared .class, "myPrivateMethod",
String.class, MyBean.class)).withArguments(anyString(), anyObject())
.thenReturn(true);// this return can be made to do nothing as well if you want
spy.myPublicMethod();
Related
I am getting following exception while running the tests. I am using Mockito for mocking. The hints mentioned by Mockito library are not helping.
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.a.b.DomainTestFactory.myTest(DomainTestFactory.java:355)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
at a.b.DomainTestFactory.myTest(DomainTestFactory.java:276)
..........
Test Code from DomainTestFactory. When I run the following test, I see the exception.
#Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
Mockito.when(mainModel.getList()).thenReturn(getSomeList()); // Line 355
}
private List<SomeModel> getSomeList() {
SomeModel model = Mockito.mock(SomeModel.class);
Mockito.when(model.getName()).thenReturn("SomeName"); // Line 276
Mockito.when(model.getAddress()).thenReturn("Address");
return Arrays.asList(model);
}
public class SomeModel extends SomeInputModel{
protected String address;
protected List<SomeClass> properties;
public SomeModel() {
this.Properties = new java.util.ArrayList<SomeClass>();
}
public String getAddress() {
return this.address;
}
}
public class SomeInputModel{
public NetworkInputModel() {
this.Properties = new java.util.ArrayList<SomeClass>();
}
protected String Name;
protected List<SomeClass> properties;
public String getName() {
return this.Name;
}
public void setName(String value) {
this.Name = value;
}
}
You're nesting mocking inside of mocking. You're calling getSomeList(), which does some mocking, before you've finished the mocking for MyMainModel. Mockito doesn't like it when you do this.
Replace
#Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
Mockito.when(mainModel.getList()).thenReturn(getSomeList()); --> Line 355
}
with
#Test
public myTest(){
MyMainModel mainModel = Mockito.mock(MyMainModel.class);
List<SomeModel> someModelList = getSomeList();
Mockito.when(mainModel.getList()).thenReturn(someModelList);
}
To understand why this causes a problem, you need to know a little about how Mockito works, and also be aware in what order expressions and statements are evaluated in Java.
Mockito can't read your source code, so in order to figure out what you are asking it to do, it relies a lot on static state. When you call a method on a mock object, Mockito records the details of the call in an internal list of invocations. The when method reads the last of these invocations off the list and records this invocation in the OngoingStubbing object it returns.
The line
Mockito.when(mainModel.getList()).thenReturn(someModelList);
causes the following interactions with Mockito:
Mock method mainModel.getList() is called,
Static method when is called,
Method thenReturn is called on the OngoingStubbing object returned by the when method.
The thenReturn method can then instruct the mock it received via the OngoingStubbing method to handle any suitable call to the getList method to return someModelList.
In fact, as Mockito can't see your code, you can also write your mocking as follows:
mainModel.getList();
Mockito.when((List<SomeModel>)null).thenReturn(someModelList);
This style is somewhat less clear to read, especially since in this case the null has to be casted, but it generates the same sequence of interactions with Mockito and will achieve the same result as the line above.
However, the line
Mockito.when(mainModel.getList()).thenReturn(getSomeList());
causes the following interactions with Mockito:
Mock method mainModel.getList() is called,
Static method when is called,
A new mock of SomeModel is created (inside getSomeList()),
Mock method model.getName() is called,
At this point Mockito gets confused. It thought you were mocking mainModel.getList(), but now you're telling it you want to mock the model.getName() method. To Mockito, it looks like you're doing the following:
when(mainModel.getList());
// ...
when(model.getName()).thenReturn(...);
This looks silly to Mockito as it can't be sure what you're doing with mainModel.getList().
Note that we did not get to the thenReturn method call, as the JVM needs to evaluate the parameters to this method before it can call the method. In this case, this means calling the getSomeList() method.
Generally it is a bad design decision to rely on static state, as Mockito does, because it can lead to cases where the Principle of Least Astonishment is violated. However, Mockito's design does make for clear and expressive mocking, even if it leads to astonishment sometimes.
Finally, recent versions of Mockito add an extra line to the error message above. This extra line indicates you may be in the same situation as this question:
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
For those who use com.nhaarman.mockitokotlin2.mock {}
Workaround 1
This error occurs when, for example, we create a mock inside another mock
mock {
on { x() } doReturn mock {
on { y() } doReturn z()
}
}
The solution to this is to create the child mock in a variable and use the variable in the scope of the parent mock to prevent the mock creation from being explicitly nested.
val liveDataMock = mock {
on { y() } doReturn z()
}
mock {
on { x() } doReturn liveDataMock
}
Workaround 2
Make sure all your mocks that should have a thenReturn.
GL
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
E.g. thenReturn() may be missing.
For mocking of void methods try out below:
//Kotlin Syntax
Mockito.`when`(voidMethodCall())
.then {
Unit //Do Nothing
}
AbcService abcService = mock(AbcService.class);
Check the syntax:
doThrow(new RunTimeException()).when(abcService).add(any(), any())
Common Mistake as seen below:
A. doThrow(new RunTimeException()).when(abcService.add(any(), any()))
Similarly, check for when().thenReturn(), so on.
I am so exited with detailed answer of #Luke Woodward that want to share a workaround.
As #Luke Woodward explained, we can not have two calls like
when(mainModel.getList());
// ...
when(model.getName()).thenReturn(...);
Than can occurs in call chain.
But in case you will use construction:
doReturn(mockToken("token3")).when(mock).getAccessToken();
when
OAuth2AccessToken mockToken(String tokenVal){
OAuth2AccessToken token = Mockito.mock(OAuth2AccessToken.class);
doReturn( 60 ).when(token).getExpiresIn();
doReturn(tokenVal).when(token).getValue();
return token;
}
all will works as expected.
Want to ask you a question.
How should I properly return some data from method called from testable class ?
For example I have next structure:
Class SomeClass {
public void method1(){
//some logic here
List<Object> howToReturnHereValues = gatData();
//some logic here
}
public List<Object> getData(){
return List<Object>;
}
}
Right now I want to test method1(), but I don't know how to mock call getData() which returns List<Object>.
Any advice please ?
You can do this using a spy, like explained here: https://static.javadoc.io/org.mockito/mockito-core/2.7.17/org/mockito/Mockito.html#13
Example:
#Test
public void testMethod1() throws Exception {
SomeClass someClass = new SomeClass();
SomeClass spy = Mockito.spy(someClass);
Mockito.when(spy.getData()).thenReturn(Arrays.asList("blaat", "blabla"));
spy.method1();
}
This will return a List of "blaat" and "blabla" which can be used by the logic in your method1.
Right now I want to test method1(), but I don't know how to mock call
getData() which returns List.
It is rather a bad idea to mock a public method of a class that is under test.
A unit test should test a behavior and mock dependencies. Here, you unit test only a part of the behavior as you mock the behavior of the tested class.
If the class is ours you could :
either test this method without mocking the getData() called public method.
or move the getData() public method in another class and then mock this new dependency if you don't want to repeat the test of the getData() method in each test method calling it.
If the class is not modifiable and the mocked called is really required, you could use the spy() method of the Mockito framework on the object under test to simulate a mocked behavior for a specific method.
I am facing an issue with Mockito junit testing. I am new to it and am a bit confused with the problem I am facing. Any help on this would be appreciated.
class Activity{
public void firstMethod(){
String str = secondMethod();
}
public String secondMethod(){
String str = null;
/* some Code */
return str;
}
}
Getting exception :
*org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!*
in the below code
class ActivityTest(){
Activity act;
#Before
public void setup(){
act = new Activity();
}
#Test
public void testFirstMethod(){
Mockito.doReturn(Mockito.anyString()).when(act).secondMethod();
act.firstMethod();
verify(act).secondMethod();
}
}
I am aware that activity is not a mock but I am not sure for a way around this as secondMethod() is a method in the same class. I need to write rule for secondMethod() as I have already done its Unit Testing. The definition of secondMethod() consists has external dependencies. Should I be mocking the external dependencies present in secondMethod() and writing rules for them rather than rule for secondMethod()?
I found this post:
Mockito Spy'ing on the object being unit tested
However separating the secondMethod() into a different class does not make sense. My method is related to this class. Creating a different class for testing does not seem right to me. Even mocking the actual class using spy() is not the most correct way as already explained in the post.
I don't think I should be creating a mock of the Activity class as that is the class I am testing. I would really appreciate help and insights into this.
As you noted, act is not a mock, and therefore you cannot record behavior on it. You could use Mockito.spy to, well, spy (or partially mock) the act object so that you only record the behavior of secondMethod and execute the actual code for firstMethod.
Note, however, that matchers can't be used in doReturn calls regardles of how you're mocking or spying your object. A return value must be a concrete object.
class ActivityTest() {
Activity act;
#Before
public void setup(){
act = Mockito.spy(new Activity()); // Here!
}
#Test
public void testFirstMethod(){
Mockito.doReturn("someString").when(act).secondMethod();
act.firstMethod();
verify(act).secondMethod();
}
}
A slightly more elegant syntax allows you to use annotations instead of explicitly calling Mockito.spy, but it's a matter of taste really:
#RunWith(MockitoJUnitRunner.class)
class ActivityTest() {
#Spy
Activity act = new Activity();
#Test
public void testFirstMethod(){
Mockito.doReturn("someString").when(act).secondMethod();
act.firstMethod();
verify(act).secondMethod();
}
}
There is no reason to mock anything in this example. Since there are no dependencies and both methods are public, you can test them directly.
public class ActivityTest() {
private Activity act = new Activity();
#Test
public void testSecondMethod(){
assertEquals("expected-value", act.secondMethod());
}
#Test
public void testFirstMethod() {
act.firstMethod();
// success if no exception occurs
}
}
Since firstMethod does not have any detectable effect on the Act instance, nor on any dependency (since there are none) you can simply call the method and be satisfied if no exception is thrown. One could also reason that such a method should not be tested at all.
I assume the example given is a simplification of a class where calling firstMethod actually does have side effects, who knows...
Here are some hints:
Mock the Activity.
Tweak the behavior of secondMethod with when / then / doReturn
Use doCallRealMethod when firstMethod is invoked.
Hope it helps.
public class First {
public First(){
}
public String doSecond(){
Second second = new Second();
return second.doJob();
}
}
class Second {
public String doJob(){
return "Do Something";
}
}
Here I want to test the method "doSecond()" of class "First". For the same, I want to mock the method "doJob" of class "Second".
I know that I can create a mocked instance of class "Second" using the code below.
Second sec = mock(Second.class);
when(sec.doJob()).thenReturn("Stubbed Second");
But I cannot relate this mocked instance with class "First" as of the current code.
Without refactoring the source code, is there any way by which i can achieve the requirement.
Please help.
Take a look at powermock's ability to intercept calls to new and return mocks instead
https://code.google.com/p/powermock/wiki/MockConstructor
This doesn't require changing any sourcecode.
here's the test code where we actually return a mock when First.doSecond() calls new Second()
#RunWith(PowerMockRunner.class)
#PrepareForTest(First.class)
public class TestFirst {
#Test
public void mockSecond() throws Exception{
Second mock = PowerMockito.mock(Second.class);
PowerMockito.whenNew(Second.class).withNoArguments().thenReturn(mock);
PowerMockito.when(mock.doSecond()).thenReturn("from mock");
First first = new First();
assertEquals("from mock", first.doSecond());
}
}
It's tricky to mock an instance that you create inside of a method, but it's possible.
Using PowerMock, you can accomplish this with the PowerMock.expectNew() method:
#RunWith(PowerMockRunner.class)
#PrepareForTest(First.class)
public class StackOverflowTest {
#Test
public void testFirst() throws Exception {
Second secondMock = EasyMock.createMock(Second.class);
PowerMock.expectNew(Second.class).andReturn(secondMock);
expect(secondMock.doSecond()).andReturn("Mocked!!!");
PowerMock.replay(secondMock, Second.class);
String actual = new First().doSecond();
PowerMock.verify(secondMock, Second.class);
assertThat(actual, equalTo("Mocked!!!"));
}
}
Effectively, PowerMock is proxying the creation of the new object and substituting whatever value we want when we invoke doSecond().
So, it's possible. However, this is a terrible practice to get into.
One typically wants to mock objects if they involve an outside concern, such as another layer (i.e. database, validation), or if the desired output is coming from other objects that are injected but are safe enough to consider tested.
If your method is capable of getting or retrieving data from a non-injectable source, you should not want to mock that out.
Considering that your method is simple and straightforward, you should really not need to do any mocks here at all. But if you felt that you were forced to, you could do one of a few things:
Create a factory for the creation of Second, and mock the results of the returning factory object with Mockito.
Pass in an instance of Second to that method, and use Mockito as the mock instance.
Declare it as a field (i.e. injected dependency), and use Mockito.
For completeness, here is how the test can be written with the JMockit mocking API, without any refactoring of the original code under test:
public class ExampleTest
{
#Test
public void firstShouldCallSecond(#Mocked final Second secondMock) {
new NonStrictExpectations() {{
secondMock.doJob(); result = "Mocked!!!";
}};
String actual = new First().doSecond();
assertEquals("Mocked!!!", actual);
}
}
Following is my class
public class SomeClass {
public ReturnType1 testThisMethod(Type1 param1, Type2 param2) {
//some code
helperMethodPublic(param1,param2);
//more code follows
}
public ReturnType2 helperMethodPublic(Type1 param1, Type2 param2) {
//some code
}
}
So in the above class while testing testThisMethod(), I want to partially mock helperMethodPublic().
As of now, I am doing the following:
SomeClass someClassMock =
PowerMock.createPartialMock(SomeClass.class,"helperMethodPublic");
PowerMock.expectPrivate(someClassMock, "helperMethodPublic, param1, param2).
andReturn(returnObject);
The compiler doesn't complain. So I try to run my test and when the code hits the helperMethodPublic() method, the control goes into the method and starts to execute each line of code in there. How do I prevent this from happening?
Another solution that doesn't rely on a mock framework would be to override 'helperMethodPublic' in an anonymous subclass defined within your test:
SomeClass sc = new SomeClass() {
#Override
public ReturnType2 helperMethodPublic(Type1 p1, Type2 p2) {
return returnObject;
}
};
Then when you use this instance in your test it will run the original version of 'testThisMethod' and the overridden version of 'helperMethodPublic'
I think it is because of what Jeff said.
Try this - setting up an expectation just as any other mocked method:
SomeClass someClassMock = PowerMock.createPartialMock(SomeClass.class,
"helperMethodPublic");
EasyMock.expect(someClassMock.helperMethodPublic(param1, param2)).
andReturn(returnObject);
PowerMock.replayAll();
I would guess this is because your "helperMethodPublic" is not a private method (as in PowerMock.expectPrivate). PowerMock is a framework that extends other mocking frameworks to add things such as mocking private and static methods (which JMock, Mockito, etc don't handle). Doing a partial mock of public methods should be something your underlying mock framework handles.