Running PowerMock with Enclosed class - java

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.

Related

JUnit Category doesn't work with TestCase?

I found a strange thing and I'm interested to know why it happens. I'm using maven surefire plugin ( 2.12.4 ) with Junit 4.11. When I wanted to use #Category annotation in order to disable some tests. the strange thing that it works correctly only with tests that don't extend TestCase. For test that don't extend TestCase I was able to put the annotation only on the test method to run/disable, but with others it disables all tests in the class.
Example:
Command Line:
mvn test -Dgroups=!testgroups.DisabledTests run only test B for the first snippet:
import static org.junit.Assert.*;
public class DataTest {
#Test
public void testA(){...}
#Test #Category(testgroups.DisabledTests.class)
public void testB(){...}
}
for the second case with class extending TestCase, it will run no tests.
public class DataTest extends TestCase {
#Test
public void testA(){...}
#Test #Category(testgroups.DisabledTests.class)
public void testB(){...}
}
Why it happens?
The solution was given in a comment by deborah-digges:
The problem is that the second class is an extension of TestCase. Since this is JUnit 3 style, the annotation #Category didn't work. Annotating the class with #RunWith(JUnit4.class) should give you the same result in both cases
and another by Stefan Birkner:
JUnit 4 finds test by looking for the #Test annotation. You can remove the extends TestCase from your test class. Furthermore the name of the test method does no longer have to start with test. You're free to choose any method name you want.

mock static without #RunWith(PowerMockRunner.class)

I have folowing code:
#RunWith(PowerMockRunner.class)
#PrepareForTest({RequestUtils.class, OsgiUtil.class})
#PowerMockIgnore({"*"})
public class MyTest
...
#Test
public somMethod(){
....
mockStatic(RequestUtils.class);
when(RequestUtils.getLocale(request)).thenReturn(locale);
}
}
How to replace this code so that it work without #RunWith(PowerMockRunner.class)?
According the cause described in following link I cannot use #RunWith(PowerMockRunner.class)
Take a look on this discussion: issues while using #RunWith Annotation and powerMock
One of the answers recommends to use PowerMockRule instead of runner. This solution should be good for you.

Mock static methods from multiple class using PowerMock

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() {
}
}

Cleanup after all junit tests

In my project I have to do some repository setup before all tests. This is done using some tricky static rules. However I've got no clue how to do clean up after all the tests. I don't want to keep some magic static number referring the number of all test methods, which I should maintain all the time.
The most appreciated way is to add some listener which would be invoked after all the tests. Is there any interface for it already in JUnit4?
edit: this has nothing to do with #BeforeClass and #AfterClass, cause I have to know if method annotated with #AfterClass is invoked for the last time.
I'm using JUnit 4.9. Will this help?:
import junit.framework.TestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({First.class,Second.class,Third.class})
public class RunTestSuite extends TestCase {
#BeforeClass
public static void doYourOneTimeSetup() {
...
}
#AfterClass
public static void doYourOneTimeTeardown() {
...
}
}
Edit: I am quite positive (unless I misunderstand your question) that my solution is what you are looking for. i.e. one teardown method after all your tests have ran. No listener required, JUnit has this facility. Thanks.
I recommend to use org.junit.runner.notification.RunListener, example:
public class TestListener extends RunListener {
#Override
public void testRunStarted(Description description) throws Exception {
// Called before any tests have been run.
}
#Override
public void testRunFinished(Result result) throws Exception {
// Called when all tests have finished
}
}
Read more directly in JUnit java doc.
You can use that even with Maven's surefire (unit tests) plugin or failsafe plugin (integration tests) by adding following code into plugin configuration:
<properties>
<property>
<name>listener</name>
<value>com.innovatrics.afismq.it.TestListener</value>
</property>
</properties>
Just encountered the same problem.
My solution:
For a global set up: use (lazy) singleton to access something global that requires instantiation before the tests. The first test that accesses this singleton will trigger the global set up process.
For a global tear down: use a Java shutdown hook: Runtime.getRuntime().addShutdownHook(new Thread(() -> do_your_global_cleanup())));
You can always write your custom TestRunner. However, before you do that you need to evaluate the need for the same. It is better to use #BeforeClass and #AfterClass. Another example I can point to is, the fashion in which hibernate allows users to do unit testing using 'import.sql'.
No need to use suite, just add #BeforeClass, and #AfterClass as static
public class Tests {
#BeforeClass
public static void doYourOneTimeSetup()
{
...
}
#AfterClass
public static void doYourOneTimeTeardown() {
...
}
#Test
public void testYourTestcase()
{
...
}
}

How to avoid inheritance in JUnit test cases?

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).

Categories