I noticed that jUnit runs the constructor of my test class for each method being tested. Here's an example:
public class TestTest {
protected BigUglyResource bur;
public TestTest(){
bur=new BigUglyResource();
System.out.println("TestTest()");
}
#Test
public void test1(){
System.out.printf("test1()\n");
}
#Test
public void test2(){
System.out.printf("test2()\n");
}
#Test
public void test3(){
System.out.printf("test3()\n");
}
}
Gives the following result:
TestTest()
test1()
TestTest()
test2()
TestTest()
test3()
Calling the constructor to BigUglyResource is too time-consuming, I'd prefer to build it only once. I know you can use #BeforeClass to run a method once, but #BeforeClass is only for static methods. Static methods can't access a class property like BigUglyResource in the example above. Other than building a Singleton, what options are there?
Can't you declare the BigUglyResource static? This is how I normally do it.
private static BigUglyResource bur;
#BeforeClass
public static void before(){
bur=new BigUglyResource();
}
You could make "bur" static:
protected static BigUglyResource bur;
And use #BeforeClass.
For JUnit5 users: you have to use #BeforeAll annotation instead of #BeforeEach, the rest stays the same as in bruno's and Russ'es answers.
private static BigUglyResource bur;
#BeforeAll
public static void before(){
bur=new BigUglyResource();
}
Related
I have the following requirement:
Create a TestSuite class which initialize some variables which are required by all test classes.
Pass this variable to all classes.
so, I created the following TestSuite class:
#RunWith(Suite.class)
#SuiteClasses({ //
LoginCommandTest.class //
})
public class GameTestSuite {
private static Vertx vertx;
#BeforeClass
public static void setUp() throws IOException
vertx = ....
...
}
}
and the test-class
public class LoginCommandTest {
#Test
public void testLogin() {
vertx.someMethod();
...
}
}
How can I pass vertx initialized in #BeforeClass of GameTestSuite into LoginCommandTest ??
If you use JUnit 5, have a look at this project, that integrates vert-x with Jupiter: https://github.com/vert-x3/vertx-junit5 It implements an extension that cares about creating and providing (a shared) vert-x context to each test container or method.
If it doesn't fit your needs, roll your own specialized extension. Details at https://junit.org/junit5/docs/current/user-guide/#extensions
It's ugly but you can make vertx public or protected and access it from LoginCommandTest like any other static variable GameTestSuite.vertx.
I have a little problem here, and I don't know how to solve it.
I have a class which have to make tests for some JSF beans.
In order to achieve that, I used PowerMock with Mockito for mocking the FacesContext, RequestContext and another static methods which are used inside the JSF beans.
#PrepareForTest(ClassWithStaticMethods.class)
#RunWith(PowerMockRunner.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass{
#BeforeClass
public static void init() throws Exception{
//mocking the FacesContext and others
}
#Test
public void test0001Create(){}
#Test
public void test0002Edit(){}
#Test
public void test0003Delete(){}
}
The SomeTestBaseClass, nothing complicated.
public abstract class SomeTestBaseClass {
#BeforeClass
public static void setUpBeforeClass() throws Exception {
//...
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
//...
}
}
The problem is that the order of tests is ignored (even with the FixMethodOrder annotation). If I remove PowerMockRunner (and the RunWith annotation), the order is kept but the mocking for static (and void) methods doesn't work.
But leaving the class with PowerMockRunner, the annotation #FixMethodOrder is ignored, totally.
I even tried with MockitoJUnitRunner, and here the order of tests is kept, but the mocking for static (and void) methods isn't done.
Does anyone have any idea why it is happening?
Thanks
I had the same problem getting them to run in the right order.
I solved it by using the #PowerMockRunnerDelegate annotation.
In my test class annotations:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
I added #PowerMockRunnerDelegate(JUnit4.class):
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(JUnit4.class)
They now run in the expected order.
I believe this works because then it's not PowerMock that's running the tests, but JUnit 4 itself.
Like a workaround: Create a new method (let's say 'testAll'), put #Test annotation just for this (remove the #Test annotation from the rest of the methods), and then, call your testing methods inside of the annoted method.
Dirty, but it works.
#PrepareForTest(ClassWithStaticMethods.class)
#RunWith(PowerMockRunner.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass{
#BeforeClass
public static void init() throws Exception{
//mocking the FacesContext and others
}
#Test
public void testAll(){
this.test0001Create();
this.test0002Edit();
this.test0003Delete();
}
public void test0001Create(){}
public void test0002Edit(){}
public void test0003Delete(){}
}
Please try to change sequence:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassWithStaticMethods.class)
I don't know why it doesn't work with the PowerMockRunner annotation but instead you could use a PowerMockRule
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass {
#Rule
public PowerMockRule rule = new PowerMockRule();
#BeforeClass
public static void init() throws Exception {
// mocking the FacesContext and others
}
#Test
public void test0001Create() {
}
#Test
public void test0002Create() {
}
#Test
public void test0003Create() {
}
}
I have few JUnit Tests and I want to decide which one to use at runtime. I checked previous answers at SO and I ended up creating Test Suite dynamically.
This class is where my application starts. I have CustomTestSuite class and Main class adds Tests to my custom suite.
public class Main {
public static junit.framework.TestSuite suite()
{
CustomTestSuite suite = new CustomTestSuite();
suite.addTest(new JUnit4TestAdapter(BTest.class));
suite.addTest(new JUnit4TestAdapter(ATest.class));
return suite;
}
}
CustomTestSuite.java
public class CustomTestSuite extends TestSuite {
#BeforeClass
public static void setUp() throws Exception {
System.out.println("Before class test");
}
#After
public void tearDown() throws Exception {
System.out.println("After class test");
}
}
My ATest and BTest are simple Test classes, I will just show ATest as sample:
public class ATest{
#Test
public void testMethod() {
System.out.println("testMethod");
}
}
When I start running my project from Main class, it is expected to run the method with #BeforeClass first, do testing, and then run the method with #AfterClass annotation.
Tests are working fine but it skips setUp method and tearDown method. I tried #Before and #BeforeClass annotations both.
I am confused with suite structure. Any help would be appreciated.
Thanks
#Before and #BeforeClass are supposed to be used in Test class not in TestSuite. If need to have common setUp and tearDown for more than one Test class, then put those both methods in a super class and extend that super by ATest and BTest test classes. And also the Suite can be built and run simply with #RunWith and #SuiteClasses annotations and the CustomTestSuite class is not needed.
So the changes are as below.
The CustomTestSuite becomes TestSuper
public class TestSuper {
#BeforeClass
public static void setUp() throws Exception {
System.out.println("Before class test");
}
#After
public void tearDown() throws Exception {
System.out.println("After class test");
}
}
Now the ATest extends TestSuper
public class ATest extends TestSuper {
#Test
public void testMethod() {
System.out.println("testMethod");
}
}
Similarly BTest also should extend TestSuper.
Simply add #RunWith and #SuiteClasses annotations to Main class as below and run Main.
#RunWith(Suite.class)
#SuiteClasses({ATest.class, BTest.class})
public class Main {
}
Have a go with these changes.
I have an Integration Test Suite. I have a IntegrationTestBase class for all my tests to extend. This base class has a #Before (public void setUp()) and #After (public void tearDown()) method to establish API and DB connections. What I've been doing is just overriding those two methods in each testcase and calling super.setUp() and super.tearDown(). However this can cause problems if someone forgets to call the super or puts them at the wrong place and an exception is thrown and they forget to call super in the finally or something.
What I want to do is make the setUp and tearDown methods on the base class final and then just add our own annotated #Before and #After methods. Doing some initial tests it appears to always call in this order:
Base #Before
Test #Before
Test
Test #After
Base #After
but I'm just a little concerned that the order isn't guaranteed and that it could cause problems. I looked around and haven't seen anything on the subject. Does anyone know if I can do that and not have any problems?
Code:
public class IntegrationTestBase {
#Before
public final void setUp() { *always called 1st?* }
#After
public final void tearDown() { *always called last?* }
}
public class MyTest extends IntegrationTestBase {
#Before
public final void before() { *always called 2nd?* }
#Test
public void test() { *always called 3rd?* }
#After
public final void after() { *always called 4th?* }
}
Yes, this behaviour is guaranteed:
#Before:
The #Before methods of superclasses will be run before those of the current class, unless they are overridden in the current class. No other ordering is defined.
#After:
The #After methods declared in superclasses will be run after those of the current class, unless they are overridden in the current class.
One potential gotcha that has bitten me before:
I like to have at most one #Before method in each test class, because order of running the #Before methods defined within a class is not guaranteed. Typically, I will call such a method setUpTest().
But, although #Before is documented as The #Before methods of superclasses will be run before those of the current class. No other ordering is defined., this only applies if each method marked with #Before has a unique name in the class hierarchy.
For example, I had the following:
public class AbstractFooTest {
#Before
public void setUpTest() {
...
}
}
public void FooTest extends AbstractFooTest {
#Before
public void setUpTest() {
...
}
}
I expected AbstractFooTest.setUpTest() to run before FooTest.setUpTest(), but only FooTest.setupTest() was executed. AbstractFooTest.setUpTest() was not called at all.
The code must be modified as follows to work:
public void FooTest extends AbstractFooTest {
#Before
public void setUpTest() {
super.setUpTest();
...
}
}
I think based on the documentation of the #Before and #After the right conclusion is to give the methods unique names. I use the following pattern in my tests:
public abstract class AbstractBaseTest {
#Before
public final void baseSetUp() { // or any other meaningful name
System.out.println("AbstractBaseTest.setUp");
}
#After
public final void baseTearDown() { // or any other meaningful name
System.out.println("AbstractBaseTest.tearDown");
}
}
and
public class Test extends AbstractBaseTest {
#Before
public void setUp() {
System.out.println("Test.setUp");
}
#After
public void tearDown() {
System.out.println("Test.tearDown");
}
#Test
public void test1() throws Exception {
System.out.println("test1");
}
#Test
public void test2() throws Exception {
System.out.println("test2");
}
}
give as a result
AbstractBaseTest.setUp
Test.setUp
test1
Test.tearDown
AbstractBaseTest.tearDown
AbstractBaseTest.setUp
Test.setUp
test2
Test.tearDown
AbstractBaseTest.tearDown
Advantage of this approach: Users of the AbstractBaseTest class cannot override the setUp/tearDown methods by accident. If they want to, they need to know the exact name and can do it.
(Minor) disadvantage of this approach: Users cannot see that there are things happening before or after their setUp/tearDown. They need to know that these things are provided by the abstract class. But I assume that's the reason why they use the abstract class
If you turn things around, you can declare your base class abstract, and have descendants declare setUp and tearDown methods (without annotations) that are called in the base class' annotated setUp and tearDown methods.
You can use #BeforeClass annotation to assure that setup() is always called first. Similarly, you can use #AfterClass annotation to assure that tearDown() is always called last.
This is usually not recommended, but it is supported.
It's not exactly what you want - but it'll essentially keep your DB connection open the entire time your tests are running, and then close it once and for all at the end.
This isn't an answer to the tagline question, but it is an answer to the problems mentioned in the body of the question. Instead of using #Before or #After, look into using #org.junit.Rule because it gives you more flexibility. ExternalResource (as of 4.7) is the rule you will be most interested in if you are managing connections. Also, If you want guaranteed execution order of your rules use a RuleChain (as of 4.10). I believe all of these were available when this question was asked. Code example below is copied from ExternalResource's javadocs.
public static class UsesExternalResource {
Server myServer= new Server();
#Rule
public ExternalResource resource= new ExternalResource() {
#Override
protected void before() throws Throwable {
myServer.connect();
};
#Override
protected void after() {
myServer.disconnect();
};
};
#Test
public void testFoo() {
new Client().run(myServer);
}
}
I have the following code:
#BeforeClass
public static void setUpOnce() throws InterruptedException {
fail("LOL");
}
And various other methods that are either #Before, #After, #Test or #AfterClass methods.
The test doesn't fail on start up as it seems it should. Can someone help me please?
I have JUnit 4.5
The method is failing in an immediate call to setUp() which is annotated as #before.
Class def is :
public class myTests extends TestCase {
do NOT extend TestCase AND use annotations at the same time!
If you need to create a test suite with annotations, use the RunWith annotation like:
#RunWith(Suite.class)
#Suite.SuiteClasses({ MyTests.class, OtherTest.class })
public class AllTests {
// empty
}
public class MyTests { // no extends here
#BeforeClass
public static void setUpOnce() throws InterruptedException {
...
#Test
...
(by convention: class names with uppercase letter)
the method must be static and not directly call fail (otherwise the other methods won't be executed).
The following class shows all the standard JUnit 4 method types:
public class Sample {
#BeforeClass
public static void beforeClass() {
System.out.println("#BeforeClass");
}
#Before
public void before() {
System.out.println("#Before");
}
#Test
public void test() {
System.out.println("#Test");
}
#After
public void after() {
System.out.println("#After");
}
#AfterClass
public static void afterClass() {
System.out.println("#AfterClass");
}
}
and the ouput is (not surprisingly):
#BeforeClass
#Before
#Test
#After
#AfterClass
Make sure you imported #Test from the correct package.
Correct package: org.junit.Test
Incorrect pacakge: org.junit.jupiter.api.Test
Please note that this is a solution for: If your #Before, #Atter, etc did not get called at all.
Make sure that :
Your test class doesn't inherits from TestCase
The #BeforeClass method is static
You don't have more than one #BeforeClass method in test class hierarchy (only the most specialized #BeforeClass method will be executed)
Check your imports.
#Before
#After
#BeforeClass (this should be static)
#AfterClass (this should be static)
and #Test annotations should import from same path.
In order that the before annotated function will run , I had to do the following:
If you use Maven , add a dependency to Junit 4.11+:
<properties>
<version.java>1.7</version.java>
<version.log4j>1.2.13</version.log4j>
<version.mockito>1.9.0</version.mockito>
<version.power-mockito>1.4.12</version.power-mockito>
<version.junit>4.11</version.junit>
<version.power-mockito>1.4.12</version.power-mockito>
</properties>
and the dependency:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
.
.
.
</dependencies>
Make sure your Junit Test class is not extending The TestCase class, since this will cause overlapping with Older version:
public class TuxedoExceptionMapperTest{
protected TuxedoExceptionMapper subject;
#Before
public void before() throws Exception {
subject = TuxedoExceptionMapper.getInstance();
System.out.println("Start");
MockitoAnnotations.initMocks(this);
}
}