I am trying to mock Static methods using PowerMockito. It works fine when I try To mock only one Class. For instance Class1.staticMethod(). But my tested class uses other static method from other class Class2.staticMethod().
So my question is: How to mock two different static methods from different classes, in the same test using PowerMockito?
I can not use mockito-inline dependency, so it should be done only with PowerMockito.
If you simply provide two static mocks you can control the behavior of each method.
I usually do something like this in Mockito:
protected static MockedStatic<Class1> CLASS1_MOCK= Mockito.mockStatic(Class1.class);
CLASS1_MOCK.when(Class1::staticMethod).thenReturn(testValue1);
protected static MockedStatic<Class2> CLASS2_MOCK = Mockito.mockStatic(Class2.class);
CLASS2_MOCK.when(Class2::staticMethod).thenReturn(testValue2);
Related
my problem is that my unit test are slow because I'm publishing in a topic in those unit test, I would like to mock or change its behavior in some way. I was thinking in use reflection for this class and change the method behavior but I'm not sure if that is possible.
This is the behavior that I like to mock or change:
TopicCall.builder()
.toTopic(XXXX)
.withAttribute(XXXXXX, XXXXX)
.withAttribute(XXXXX, XXXXXX)
.withAttribute(XXXXX,XXXXX)
.publish();
I would like to do this because publis() is a real invocation and the test is slow and causing some problems in jenkins, because several unit test are publishing at the same time.
The Topic class is a public class with a static builder method which return a class instance, just like the next one:
public static TopicCall builder() {
return new TopicCall();
}
My problem is that I just acceding the method of this class from outside and I'm not sending the class in the constructor as example and I'm not able to mock its behavior, I'm not able to modify the TopicCall class because it is a .class utility from a jar, besides that I'm not able to use PowerMockito or another library, just Mockito, is there any way to achieve that?
Thanks!
Disclaimer: I missed the fact that PowerMock is forbidden for the author, but the answer could be useful for other users with the same problem.
PowerMock
As far as you want to mock a static method, then Mockito is not the solution.
This could be done using PowerMock.
PowerMock uses ClassLoader way for mocking, which could significantly increase tests time to run.
Here is an examle on Baeldung how to mock static methods.
Solution scratch:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ TopicCall.class })
public class Test {
#Test
void test() {
mockStatic(TopicCall.class);
when(TopicCall.builder()).thenReturn(/*value to be returned*/ null);
// the test code...
}
}
I am facing problem while testing method using Mockito.
please check testMethodToBeTested() method of JunitTestCaseClass, which has to handle static method call of thirdparty class.
class ClasssToBeTested{
public String methodToBeTested() {
String result = ThirdPartyUtilClass.methodToBeCall();
return result;
}
}
class ThirdPartyUtilClass{
public static String methodToBeCall(){
return "OK";
}
}
// JunitTestCase which will test method "methodToBeTested()" of ClasssToBeTested class
class JunitTestCaseClass{
#InjectMocks
private ClasssToBeTested classsToBeTested;
#Test
public void testMethodToBeTested() {
//How to handle ThirdPartyUtilClass.methodToBeCall(); statement in unit testing
String result = classsToBeTested.methodToBeTested();
Assert.assertNotNull(result);
}
}
Please help & Thanks in Advance.
I think this is your answer why it is not working:
https://github.com/mockito/mockito/wiki/FAQ
What are the limitations of Mockito
Mockito 2.x specific limitations
Requires Java 6+
Cannot mock static methods
Cannot mock constructors
Cannot mock equals(), hashCode().
Firstly, you should not mock those methods. Secondly, Mockito defines and depends upon a specific implementation of these methods. Redefining them might break Mockito.
Mocking is only possible on VMs that are supported by Objenesis. Don't worry, most VMs should work just fine.
Spying on real methods where real implementation references outer Class via OuterClass.this is impossible. Don't worry, this is extremely rare case.
If you really want to mock static methods then PowerMock is your solution.
https://github.com/powermock/powermock/wiki/mockito
I need to mock enum class. (Using Mockito and PowerMockito in TestNG)
I was searching for solution, and as a result I found many similar answers:
http://ambracode.com/index/show/285802
How to mock an enum singleton class using Mockito/Powermock?
mocking a singleton class
How to mock a method in an ENUM class?
In each provided solution I need to add #PrepareForTest adnotation and mock using powermock.
#PrepareForTest( MyEnum.class)
#Test
public void myTest() {
MyEnumClass mockInstance = PowerMockito.mock(MyEnumClass .class);
Whitebox.setInternalState(MyEnumClass.class, "INSTANCE", mockInstance);
PowerMockito.mockStatic(MyEnumClass.class);
//DoReturn/when and so on...
}
But I still do not understand how it suposed to work? If I try it, I will get
java.lang.IllegalArgumentException: Cannot subclass final class class
How I can make "MyEnumClass mockInstance = PowerMockito.mock(MyEnumClass .class);" if it is enum and final?
I had that problem before i started searching for the result, but every answer looks the same.
What am I missing?
Using Mockito I want to mock a property of a class so I can verify the output
public class MyClass extends ThirdPartyFramework {
Output goesHere;
#Override
protected setup(){
goesHere = new Output();
}
//...
}
public abstract class ThirdPartyFramework {
protected setup(){...}
//...
}
I need to inject a mock of the Output class so I can validate that my code wrote the correct output.
But I can't just #InjectMock because the setup() method is called
mid-runtime and overwrites my injection.
And I can't just make setup public in MyClass because the test code I'm working
with is generic and needs to work for all subclasses of
ThirdPartyFramework, so I only have a reference to ThirdPartyFramework, meaning setup() is protected.
Are you set on Mockito? I am asking since Mockito FAQMockito FAQ states that it doesn't support mocking static methods, which I guess you'd need in this case for the setup method to create your mock instead of real Output.
I have used PowerMock for a similar scenario:
whenNew(NewInstanceClass.class).withArguments(any()).thenReturn(mockObject);
which says that each time a NewInstanceClass gets created my mockObject be returned no matter what constructor arguments had been used and who constructed NewInstanceClass at what time.
In PowerMock docs I've also found following example:
PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject)
Actually you could use it even if you are bound to Mockito, PowerMock contains helpers for Mockito to solve exactly this problem that let you use Mockito for all tests and PowerMock to mock constructing objects. Like this:
whenNew(Output.class).withNoArguments().thenReturn(yourOutputMock);
I ended up solving this by wrapping ThirdPartyFramework and placing that class in the same package as the ThirdPartyFramework class.
That way I could mock the protected methods with Mockito. Then I was able to use #InjectMock to inject a mock of the Output object and control its method calls via that mock.
How about adding a setter for "goesHere" and then have setup() check and only change the value of goesHere if its null. This way you could inject a value in testing that would not be overridden. Something like:
protected void setGoesHere( Output output ){
goesHere = output;
}
#Override
protected void setup(){
if(goesHere != null) goesHere = new Output();
}
Hope this helps.
I know how to mock static methods from a class using PowerMock.
But I want to mock static methods from multiple classes in a test class using JUnit and PowerMock.
Can anyone tell me is it possible to do this and how to do it?
Just do #PrepareForTest({Class1.class,Class2.class}) for multiple classes.
#Test
#PrepareForTest({Class1.class, Class2.class})
public final void handleScript() throws Exception {
PowerMockito.mockStatic(Class1.class);
PowerMockito.mockStatic(Class2.class);
etc...
If you are using kotlin, the syntax is this
#PrepareForTest(ClassA::class, ClassB::class)
In java with powermock/junit, use #PrepareForTest({}) with as many static classes as you want as array ({}).
#RunWith(PowerMockRunner.class)
#PrepareForTest({XmlConverterA.class, XmlConverterB.class})
class TransfersServiceExceptionSpec {
}
I have used powermock with in scala/junit, as scalatest does not have integration with powermock.
#RunWith(classOf[PowerMockRunner])
#PrepareForTest(Array(classOf[XmlConverterA], classOf[XmlConverterB]))
class TransfersServiceExceptionSpec {
#Test
def test() {
}
}