In JUnit 4, you could use #BeforeAll in a Test Suite and assign a global variable inside the class being called. See below
#SuiteClasses({
PassFail.class
})
public class TestSuiteTest
{
public static TestConfig config = new TestConfig();
#BeforeAll
public static void configure()
{
PassFail.config=config;
}
}
But with JUnit 5, you cannot pass a value to a global variable in the class. If you try, it will be ignored since #BeforeAll is ignored in #Suite for JUnit 5. Is there a way to pass a value to a global parameter when used in #Suite for JUnit 5, similar to how JUnit 4 did? I am using Maven as my build tool. I need a way to do this because I have six different test suites using the same classes but using different values for config.
Something like this
#Suite
#SelectClasses({
PassFail.class.config = config
})
public class TestSuiteTest {
public static TestConfig config = new TestConfig();
}
Where the config value instantiated in the TestSuiteTest class body is used to assign the global parameter in the PassFail class.
I'm able to initiate Spring when i'm debbuging StepDefinitions.java, but running the test from gradle produces null. Do I need an aditional glue?
Produces null: gradle cucumber
Produces null: running myFeature.features
Produces myService (working): running Stepdefinitions.java
I have tried the following code:
#ContextConfiguration(
classes = Application.class,
loader = SpringBootContextLoader.class)
#WebAppConfiguration
Current StepDefinitions:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = Application.class)
#WebAppConfiguration
public class StepDefinitions{
private static String roll;
#Autowired
MyService myService;
/** Reset all static values before running test cases */
#BeforeClass
public static void resetValues() {
roll = "";
}
//I use swedish, "Given"
#Givet("Jag har rollen {string}")
public void getRole(String roll) {
assertNotNull(roll);
this.roll = roll;
myService.useRole(roll);
}
}
gradle.build:
dependencies {
compile files('../libs/cucumber-spring-4.7.1.jar')
testCompile 'io.cucumber:cucumber-java:' + cucumberVersion
testCompile 'io.cucumber:cucumber-junit:' + cucumberVersion
...
}
task cucumber() {
dependsOn assemble, compileTestJava
doLast {
javaexec {
main = "cucumber.api.cli.Main"
classpath = configurations.cucumberRuntime +
sourceSets.main.output + sourceSets.test.output
args = ['--plugin', 'pretty', '--glue', 'steps/rufs',
'src/test/resources/features', '--tags','#rufs']
}
}
}
You are not getting JUnit involved anywhere when running from Gradle. #RunWith is used by JUnit, and this in turn is what prompts Spring to get involved. When Cucumber is running as your suite, it's ignoring those annotations because it doesn't understand them.
You'll need to use JUnit as your suite (i.e. not run cucumber.api.cli.Main). You then have a problem because you need to use two "runners": Cucumber and Spring.
The way around this is JUnit's "rules" for one of the runners. Spring has a Rule, but as far as I can see Cucumber does not. In this case, use the Cucumber runner:
#RunWith(Cucumber.class)
in combination with Spring's rules, as described here: How to run JUnit SpringJUnit4ClassRunner with Parametrized?
I'm running a jUnit 3 Testcase via jUnit4/Eclipse.
Here is my custom JUnit38ClassRunner:
public class CR extends JUnit38ClassRunner{...}
So I run my Testcase:
#RunWith(CR.class)
public class TC extends TestCase
{...}
Everything works fine...
Here is my Testsuite:
public class TS {
public static Test suite() {
TestSuite result = new TestSuite();
result.addTest(new TestSuite(TC.class));
return result;
} }
How can i achieve, that TC is running through my custom runner CR in this Testsuite?
Thanks
I write unit test and want to use JUnitParamsRunner and MockitoJUnitRunner for one test class.
Unfortunately, the following does not work:
#RunWith(MockitoJUnitRunner.class)
#RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}
Is there a way to use both, Mockito and JUnitParams in one test class?
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.
As of JUnit 4.7 and Mockito 1.10.17, this functionality is built in; there is an org.mockito.junit.MockitoRule class. You can simply import it and add the line
#Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
to your test class.
This solution works for every possible runner, not just this mockito example. For example; for Spring, just change the runner classes and add necessary annotations.
#RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
#Test
public void subRunner() throws Exception {
JUnitCore.runClasses(TestMockitoJUnitRunner.class);
}
#RunWith(MockitoJUnitRunner.class)
public static class TestMockitoJUnitRunner {
}
}
DatabaseModelTest will be run by JUnit. TestMockitoJUnitRunner depends on it (by logic) and it will be run inside of the main in a #Test method, during the call JUnitCore.runClasses(TestMockitoJUnitRunner.class). This method ensures the main runner is started correctly before the static class TestMockitoJUnitRunner sub-runner runs, effectively implementing multiple nested #RunWith annotations with dependent test classes.
Also on https://bekce.github.io/junit-multiple-runwith-dependent-tests
Since the release of PowerMock 1.6, you can do it as easily as
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}
Explained here https://blog.jayway.com/2014/11/29/using-another-junit-runner-with-powermock/
In my case I was trying to Mock some method in spring bean and
MockitoAnnotations.initMocks(test);
doesn't works. Instead you have to define that bean to constructed using mock method inside your xml file like following.
...
<bean id="classWantedToBeMocked" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.fullpath.ClassWantedToBeMocked" />
</bean>
...
and add that bean with autowired inside your test class like following.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations="file:springconfig.xml")
public class TestClass {
...
#Autowired
private ClassWantedToBeMocked classWantedToBeMocked;
...
when(classWantedToBeMocked.methodWantedToBeMocked()).thenReturn(...);
...
}
check out this link https://bekce.github.io/junit-multiple-runwith-dependent-tests/
using this approach i combined a #RunWith(Parameterized.class) - outer runner - with #RunWith(MockitoJUnitRunner.class) - inner runner. The only tweak i had to add was to make my member variables in the outer class/runner static in order to make them accessible for the inner/nested runner/class. gook luck and enjoy.
I wanted to run SWTBotJunit4ClassRunner and org.junit.runners.Parameterized at the same time, I have parametric tests and I want to screenshots when the SWT test fails (the screenshot feature is provided by the SWTBotJunit4ClassRunner). #bekce's answer is great and first wanted go that route but it was either quirky passing through the arguments. Or doing the parametrized in the subclass and loosing the information what exact tests passed/failed and have only the last screenshot (as the screenshot names get the name from the test itself). So either way it was bit messy.
In my case the SWTBotJunit4ClassRunner is simple enough, so I cloned the source-code of the class, gave it my own name ParametrizedScreenshotRunner and where original was extending the TestRunner, my class is extending the Parameterized class so in essence I can use my own runner instead of the previous two. Boiled down my own runner extends on top of Parameterized runner while implementing the screenshot feature on top of it, now my test use this "hybrid" runner and all the tests work as expected straight away (no need to change anything inside the tests).
This is how it looks like (for sake of brevity I removed all the comments from the listing):
package mySwtTests;
import org.junit.runners.Parameterized;
import org.eclipse.swtbot.swt.finder.junit.ScreenshotCaptureListener;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
public class ParametrizedScreenshotRunner extends TestRu Parameterized {
public ParametrizedScreenshotRunner(Class<?> klass) throws Throwable {
super(klass);
}
public void run(RunNotifier notifier) {
RunListener failureSpy = new ScreenshotCaptureListener();
notifier.removeListener(failureSpy); // remove existing listeners that could be added by suite or class runners
notifier.addListener(failureSpy);
try {
super.run(notifier);
} finally {
notifier.removeListener(failureSpy);
}
}
}
While there are no solution in JUnit 4 it is possible to register multiple extensions in JUnit 5:
#ExtendWith(MockitoExtension.class)
#ExtendWith(AnotherExtension.class)
public class MyTest {
// some tests
}
Note that JUnitParams framework is built into JUnit 5.
You can also try this:
#RunWith(JUnitParamsRunner.class)
public class AbstractTestClass {
// some tests
}
#RunWith(MockitoJUnitRunner.class)
public class DatabaseModelTest extends AbstractTestClass {
// some tests
}
I want to add testfiles to a testsuite at runtime and my test files are not extending to Testcase as i am using junit 4.11.
Below is the code:
#RunWith(org.junit.runners.AllTests.class)
class MasterTester extends TestCase{
public static TestSuite suite1() {
TestSuite suite = new TestSuite();
for(Class<? extends TestCase> klass : gatherTestClasses()) {
suite.addTestSuite(klass);
}
return suite;
}
private static Class<?> gatherTestClasses()
{
return AbcIT.class;//getting a compile time error
}
}
I am getting a compile time error saying class of type cannot be added to class
Please suggest?
Perhaps have a look at #Andrejs answer over here as he mentions dynamically adding JUnit 4 testcases to a testsuite:
#RunWith(AllTests.class)
public class SomeTests
{
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new JUnit4TestAdapter(Test1.class));
suite.addTest(new JUnit4TestAdapter(Test2.class));
return suite;
}
}