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() {
}
}
Related
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);
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 have a problem about running PowerMock with #Runwith(Enclosed.class) in pararell.
My test class structure:
#RunWith(PowerMockRunner.class)
#PrepareForTest(UnitBuild.class)
public class ut_QueueBuild{
#Test
public void someTest(){}
public static InnerTestClass{
#Test
public void someInnerTest(){}
}
}
Before using powerMock I just used:
#RunWith(Enclosed.class)
public class unitTestClass {
...
But since I am using PowerMock there is no possibility to use in pararell
#Runwith(PowerMockRunner.class)
and
#Runwith(Enclosed.class)
How can I solve this ?
Thanks a lot !
Actually you can use PowerMockRunnerDelegate and do:
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(Enclosed.class)
#PrepareForTest(MyStaticClass.class)
public class ut_QueueBuild{
#Test
public void someTest(){}
public static InnerTestClass{
#Test
public void someInnerTest(){}
}
}
This applies also to other runners, like the Parametrized.
JUnit4 only supports one #RunWith annotation, and JUnit4's #RunWith annotation doesn’t accept multiple runners.Reference: project13
Possible duplicate question but here's the answer from this StackOverflow Question #Matthew Farwell
No, you either need to:
use one and create a test base class that does the things you wanted
the other runner to do. separate your test into multiple tests, each
using different runners.
I have a number of test cases in JUnit. All of them need the same code to be executed in their #BeforeClass static method. It's a code duplication and I'm trying to get rid of it. A dirty way of doing this is by inheritance. Are there any other mechanisms in JUnit, that may help?
PS. I wrote this blog post about this very subject: http://www.yegor256.com/2015/05/25/unit-test-scaffolding.html
The JUnit way to compose reusable code (instead of inheriting from it) are Rules.
See https://github.com/junit-team/junit/wiki/Rules
Here is a dumb sample, but you'll get the point.
import org.junit.rules.TestRule;
import org.junit.runners.model.Statement;
import org.junit.runner.Description;
public class MyTestRule implements TestRule {
#Override
public Statement apply(final Statement statement, Description description) {
return new Statement() {
public void evaluate() throws Throwable {
// Here is BEFORE_CODE
try {
statement.evaluate();
} finally {
// Here is AFTER_CODE
}
}
};
}
}
You can then use your TestRule like this:
import org.junit.Rule;
public class MyTest {
#Rule
public MyTestRule myRule = new MyTestRule();
}
BEFORE_CODE and AFTER_CODE will then be executed around each of your test methods.
If you need to run your code only once per class, use your TestRule as a #ClassRule:
import org.junit.ClassRule;
public class MyTest {
#ClassRule
public static MyTestRule myRule = new MyTestRule();
}
Now, BEFORE_CODE and AFTER_CODE will be executed around each of your test class.
#Rule field is not static, #ClassRule field is.
A #ClassRule can be declared in a Suite too.
Note that you can declare several rules in a single test class, that's how you compose test lifecycles at test-suites, test-classes and test-methods levels.
A Rule is an object that you instanciate in your test classes (statically or not). You can add contructor parameters if needed.
HTH
If the method is some kind of utility, then separate it out to a different class with a static method and call that method in your #BeforeClass.
I emphasize on the fact that don't use inheritance just because it solves your problem, use it when doing so creates sense in your class hierarchy.
You may create test runner
public class MyTestRunner extends BlockJUnit4ClassRunner {
#Override
protected Object createTest() throws Exception {
Object test = super.createTest();
doStuff();
}
public void doStuff(){
//common code
}
}
#RunWith(MyTestRunner.class)
public class MyTest1{
#Test
public void test1(){
//test method
}
}
Static methods aren't inherited, so inheritance isn't an option by default. If you mean you're moving the method to a common parent class, then that seems a poor choice since you only get one parent in Java. A test support class of some sort would seem more appropriate. It's also possible that you're seeing a need for a parameterized test.
There is absolutely nothing wrong with inheritance in this case, it's actually the only way to avoid repeating this code in each subclass. The fact that #BeforeClass methods have to be declared static in JUnit is unfortunate, but that shouldn't stop you. Extend the class and you have the initialization code automatically run for you without having to do anything.
If each and every class needs to have a #BeforeClass annotated method that is exactly the same as every other, then inheritance does not feel that wrong to me. If each of these initializing methods simply share some code, you could make a TestUtil class with some shared behavior and make calls to this shared behavior from each of the #BeforeClass methods.
I think if the classes has "is-a" relation, inheritance is reasonable.
If the base class is MyBeforeClass which defines #BeforeClass method, and MyTestClass1 "is-a" MyBeforeClass, MyTestClass1 extends MyBeforeClass is OK.
Depending on the nature of the setup code, you can potentially put all your tests in a test suite and have the setup code run there. The downside to this is that you cannot run tests individually (since the test depends on the setup code).