Multiple RunWith Statements in jUnit
You cannot do this because according to spec you cannot put the same annotation twice on the same annotated element.
So, what is the solution? The solution is to put only one @RunWith()
with runner you cannot stand without and replace other one with something else. In your case I guess you will remove MockitoJUnitRunner
and do programatically what it does.
In fact the only thing it does it runs:
MockitoAnnotations.initMocks(test);
in the beginning of test case. So, the simplest solution is to put this code into setUp()
method:
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
I am not sure, but probably you should avoid multiple call of this method using flag:
private boolean mockInitialized = false;
@Before
public void setUp() {
if (!mockInitialized) {
MockitoAnnotations.initMocks(this);
mockInitialized = true;
}
}
However better, reusable solution may be implemented with JUnt's rules.
public class MockitoRule extends TestWatcher {
private boolean mockInitialized = false;
@Override
protected void starting(Description d) {
if (!mockInitialized) {
MockitoAnnotations.initMocks(this);
mockInitialized = true;
}
}
}
Now just add the following line to your test class:
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
and you can run this test case with any runner you want.
Multiple runwith for a junit test class
You can't use two runners as it noted in the commented post. You should use the Parameterized
runner as use Spring's TestContextManager to load the Spring context.
@Before
public void before() throws Exception {
new TestContextManager(getClass()).prepareTestInstance(this);
}
how to combine @RunWith with @RunWith(Parameterized.class)
I believe this does what you want:
package so.junit.runner;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.model.InitializationError;
import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters;
import org.junit.runners.parameterized.ParametersRunnerFactory;
import org.junit.runners.parameterized.TestWithParameters;
import java.util.Arrays;
@RunWith(Parameterized.class)
@Parameterized.UseParametersRunnerFactory(CustomParameterizedTest.RunnerFactory.class)
public class CustomParameterizedTest {
@Parameterized.Parameters
public static Iterable<Integer> data() {
return Arrays.asList(new Integer[]{1, 2, 3});
}
private int i;
public CustomParameterizedTest(int i) {
this.i = i;
}
@Test
public void test() {
System.out.println(i);
}
public static class RunnerFactory implements ParametersRunnerFactory {
@Override
public org.junit.runner.Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
return new A(test);
}
}
public static class A extends BlockJUnit4ClassRunnerWithParameters {
private final Object[] parameters;
public A(TestWithParameters test) throws InitializationError {
super(test);
parameters = test.getParameters().toArray(new Object[test.getParameters().size()]);
}
@Override
public Object createTest() throws Exception {
return getTestClass().getOnlyConstructor().newInstance(parameters);
}
}
}
Based on the Javadocs in the JUnit Parameterized class, this is how they expect you to create a custom test runner that supports parameterization.
UPDATE
Updated to name the custom runner A
Multiple RunWith Statements in jUnit
You cannot do this because according to spec you cannot put the same annotation twice on the same annotated element.
So, what is the solution? The solution is to put only one @RunWith()
with runner you cannot stand without and replace other one with something else. In your case I guess you will remove MockitoJUnitRunner
and do programatically what it does.
In fact the only thing it does it runs:
MockitoAnnotations.initMocks(test);
in the beginning of test case. So, the simplest solution is to put this code into setUp()
method:
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
I am not sure, but probably you should avoid multiple call of this method using flag:
private boolean mockInitialized = false;
@Before
public void setUp() {
if (!mockInitialized) {
MockitoAnnotations.initMocks(this);
mockInitialized = true;
}
}
However better, reusable solution may be implemented with JUnt's rules.
public class MockitoRule extends TestWatcher {
private boolean mockInitialized = false;
@Override
protected void starting(Description d) {
if (!mockInitialized) {
MockitoAnnotations.initMocks(this);
mockInitialized = true;
}
}
}
Now just add the following line to your test class:
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
and you can run this test case with any runner you want.
Junit testing with multiple if statements
Well, in the real world, you would rather work the other way round: you would do TDD. Meaning: you think about an (ideally small) feature that your production code should have. Then you write a test for that, and you check that the test fails. Then you implement the feature, and now the test should pass.
Writing tests "after the facts" is most often less helpful. But in general: not a big deal. You can look at your code, and observe what is doing. Then you write tests to check that behavior.
Like:
@Test(expected=IllegalArgumentException.class)
public void testWithNegativeCapacity() {
new HashMap<String, String>(-1, 0.5);
}
First you write tests that check that your code that validates inputs throws up as expected.
Then you would continue, for example like
@Test
public void testForExpectedCapacity() {
assertThat(new HashMap<String, String>(10, 0.5).getCapacity(), is(whatever));
}
Where:
- assertThat is one of the many "asserts" that you can use
is()
is a hamcrest matcher that you use with assertThat, leading to readable test code- whatever would be the value you expect that the capacity is when calling that constructor with 10 and 0.5 (I am to lazy to compute the real expected result)
Finally: of course you can look at the implementation of the production code to derive tests. But you should also look at the contract of that code.
For example its documentation: try to understand what the code is supposed to do, and write tests that verify if these claims "when you do this, code does that" really hold.
Both sides are important, and only together you can get to a complete test suite. You want to ensure that the code does what it should do, and you want to verify that "how it is done" is correct!
Related Topics
Service Layer and Controller: Who Takes Care of What
Multiple Axes on the Same Data
The Easiest Way to Transform Collection to Array
In Which Thread Do Completablefuture's Completion Handlers Execute
Should I Use a Separate Scriptengine and Compiledscript Instances Per Each Thread
Class Javalaunchhelper Is Implemented in Two Places
Httpclient 4.0.1 - How to Release Connection
How to Retrieve the Autoincrement Id from a Prepared Statement
String Variable Interpolation Java
How to Deal with Maven-3 Timestamped Snapshots Efficiently
How to Make Cartesian Product with Java 8 Streams
Display Mouse Coordinates Near Mouse as Hints on Mouse Move
Use of the Manifest.Mf File in Java
How to Efficiently Remove All Null Elements from a Arraylist or String Array