I got a method that I call at the end of every test to reset the streams positions.
Test{
[....]
reset();
}
Is there any elegant way to avoid such a repetition?
Try #After annotaton, that goes with JUnit.
Example from source:
public class Example {
File output;
#Before public void createOutputFile() {
output= new File(...);
}
#Test public void something() {
...
}
#After public void deleteOutputFile() {
output.delete();
}
}
the other answers suggest the #After annotation on a public method (preferably with name teardown) which is technically right and a good answer to your question.
But essential properties of unittests is that they need to be fast and independent of each other.
Therefore the better approach is to use a fresh mock of the stream with every test. This is best done by using a mocking framework like Mockito, JMock or alike.
Yes, create new method with #After annotation.
You should use the #After annotation - indicates something needs to be done at the end of each method run.
Use #After annotation.
#Test
public void testSomething() {
// test goes here
}
#After
public void doSomethingAfterTest() {
// reset
}
As others have pointed out, there are the #s: Before and After. Class instance methods with these annotations will run before/after every test case.
There is also BeforeClass and AfterClass, which I didn't see anyone point out yet. These #s may be put onto static methods of your class, and those methods will execute before and after all of the tests in your class have completed. It is handy in certain situations.
Related
Example code:
public class Count {
static int count;
public static int add() {
return ++count;
}
}
I want test1 and test2 run totally separately so that they both pass. How can I finish that? My IDE is Intellij IDEA.
public class CountTest {
#Test
public void test1() throws Exception {
Count.add();
assertEquals(1, Count.count);//pass.Now count=1
}
#Test
public void test2() throws Exception {
Count.add();
assertEquals(1, Count.count);//error, now the count=2
}
}
Assume the test1 runs before test2.
This is just a simplified code. In fact the code is more complex so I can't just make count=0 in #after method.
There is no automated way of resetting all the static variables in a class. This is one reason why you should refactor your code to stop using statics.
Your options are:
Refactor your code
Use the #Before annotation. This can be a problem if you've got lots of variables. Whilst its boring code to write, if you forget to reset one of the variables, one of your tests will fail so at least you'll get chance to fix it.
Use reflection to dynamically find all the member of your class and reset them.
Reload the class via the class loader.
Refactor you class. (I know I've mentioned it before but its so important I thought it was worth mentioning again)
3 and 4 are a lot of work for not much gain. Any solution apart from refactoring will still give you problems if you start trying to run your tests in parallel.
Use the #Before annotation to re-initialize your variable before each test :
#Before
public void resetCount(){
Count.count = 0;
}
Are there any best practices to get Junit execute a function once in a test file , and it should also not be static.
like #BeforeClass on non static function?
Here is an ugly solution :
#Before void init(){
if (init.get() == false){
init.set(true);
// do once block
}
}
well this is something i dont want to do , and i am looking for an integrated junit solution.
A simple if statement seems to work pretty well too:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:test-context.xml"})
public class myTest {
public static boolean dbInit = false;
#Autowired
DbUtils dbUtils;
#Before
public void setUp(){
if(!dbInit){
dbUtils.dropTables();
dbUtils.createTables();
dbInit = true;
}
}
...
To use an empty constructor is the easiest solution. You can still override the constructor in the extended class.
But it's not optimal with all the inheritance. That's why JUnit 4 uses annotations instead.
Another option is to create a helper method in a factory/util class and let that method do the work.
If you're using Spring, you should consider using the #TestExecutionListeners annotation.
Something like this test:
#RunWith(SpringJUnit4ClassRunner.class)
#TestExecutionListeners({CustomTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
#ContextConfiguration("test-config.xml")
public class DemoTest {
Spring's AbstractTestExecutionListener contains for example this empty method that you can override:
public void beforeTestClass(TestContext testContext) throws Exception {
/* no-op */
}
NOTE: DO NOT overlook/miss DependencyInjectionTestExecutionListener while adding custom TestExecutionListeners. If you do, all the autowires will be null.
If you don't want to set up static initializers for one time initialization and are not particular about using JUnit, take a look at TestNG. TestNG supports non-static, one-time initialization with a variety of configuration options, all using annotations.
In TestNG, this would be equivalent to:
#org.testng.annotations.BeforeClass
public void setUpOnce() {
// One time initialization.
}
For teardown,
#org.testng.annotations.AfterClass
public void tearDownOnce() {
// One time tear down.
}
For the TestNG equivalent of JUnit 4's #Before and #After, you can use #BeforeMethod and #AfterMethod respectively.
Easily use #BeforeAllMethods/#AfterAllMethods annotations to run a method inside the instance context (non-static), where all injected values will be available.
There is a special testing library for this:
https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0
https://bitbucket.org/radistao/before-after-spring-test-runner/
The only limitation: works only for Spring testing.
(I'm the developer of this testing library)
I've never tried but maybe you can create a no-argument constructor and call you function from there?
The article discuss 2 very nice solutions for this problem:
"clean" junit with custom Runner (using interface but you could extend it with a custom annotation e.g. #BeforeInstance)
Spring execution listeners as mentioned by Espen before.
UPDATE: Please see the comment by Cherry for why the suggestion below is flawed. (Am keeping the answer on here rather than deleting as the comment may provide useful information to others as to why this doesn't work.)
Another option worth considering if using dependency injection (e.g. Spring) is #PostConstruct. This will guarantee dependency injection is complete, which wouldn't be the case in a constructor:
#PostConstruct
public void init() {
// One-time initialization...
}
Just use #BeforeClass:
#BeforeClass
public static void init() {
}
It doesn't make sense for init to be non-static because each test is run in a separate instance. The instance
that init is run on would not match the instance of any test.
The only reason that you might want it to be non-static is to override it in subclasses, but you can do this
with static methods too. Just use the same name, and only the subclass init method will be called.
I am not sure if it is possible to do, but I need to call different #Before methods depending on Tests. Is it possible, to make some resolver for it?
#Before
performBeforeOne();
#Before
performBeforeTwo();
#Test
callBeforeOneAndExecuteTestOne();
#Test
callBeforeTwoAndExecuteTestTwo();
Or should I just create several methods and call them manually from each test?
No, you can only have one method with each lifecycle annotation. Create a composite method that calls the others if they're too large to combine.
I think the best way to achieve this (and the clearest) is to refactor your tests as such:
#Before
public void performBeforeForAll() {}
#Test
testOne() {
testOneBefore();
//.. test execution
}
#Test
testTwo() {
testTwoBefore();
//.. test execution
}
private void testOneBefore() {}
private void testTwoBefore() {}
That way, you can see exactly what each test is setting up before it runs. You will probably find that some tests share the same setup code, in which can you have a private method already there to prevent duplication.
Is there any way I can get the test result in the teardown (#After) method? I'd like to do clean up after the tests depending on the result.
Could not find much details about #After in the junit docs.
The closest thing to what you're asking for would probably be the TestWatcher rule. That won't give you access to a returned result or anything, but you can use it (or create your own TestRule and combined with the Description object, you could annotate your methods differently to indicate what sort of clean-up is necessary.
Yes, if you use TestNG, it is a standard function, your #After method can look like this:
#AfterTest
public void cleanUp( ITestResult result ) {
boolean success = result.isSuccess();
....
If there is no standard possibility (I'm pretty sure there was no possibility in JUnit 3.x), you can just
write a Listener,
push the Listener-events to a static Collection,
and gather them from your #After- Method.
Why not set the result of a test in a class member and then act on it in the #After method?
public enum TestResult {
...
}
public class TestClass {
private TestResult result;
...
#Test
public void aTest() {
// set up test
// call class under test
// assert something and set result based upon outcome
this.result = ...;
}
...
#After
public void teardown() {
// clean up based upon this.result
}
}
I suspect you would not have too many different results and a finite set will suffice.
I am using something alike JamesB suggested. You might get to the point where you have to add timeouts to the tests, then =>>
"setting the result of a test in a class member and then act on it in the #After method" would not always work if you have more than 1 assert. That's is my problem today, when i have testCaces that timeout, but my afterClass is assuming everything went smooth because the most recent assert has passed..
Are there any documented conventions for the order in which method types are placed within JUnit tests? I typically have the following order: #Before, #Test, #After; I have also seen: #Test, #Before, #After.
Example methods:
public class SandBoxTest {
SandBox sand;
#BeforeClass
public void classSetup() { }
#Before
public void given() { }
#Test
public void shouldTestThis() { }
// support method
private boolean doStuff() {
return true;
}
#Test
public void shouldTestThat() { }
#After
public void cleanUp() { }
#AfterClass
public void classCleanUp() { }
}
If there is a 'standard' convention, please provide references.
I think there is no such a coding convention but don't forget about the #Rule annotation.
http://blog.schauderhaft.de/2009/10/04/junit-rules/
I had this discussion with one of my colleagues. I was arguing for the order #BeforeClass, #Before, #After, #AfterClass, and then all the #Test, whereas he wanted the order to be #BeforeClass, #Before, all the #Test, and then #After, #AfterClass.
My arguments for having the setUp and tearDown methods at the top were:
You can easily see the conditions of the tests when you enter the test class.
Many times the tearDown is a reflection of something done in the setUp. In that case it can be useful to have them both on screen to make it easier to see that they match each other.
You dont have to scroll to the bottom to find out if there is any tearDown (which we usually don't have in the tests classes in our project).
His argument for having the tests in between the setUp and tearDown methods was that it was the logical order, which also reflects the order in which the methods are excecuted.
We searched for a convention on the Internet but didn't find any so in the end we agreed to disagree and decided that both orders were accepted in the project.
This may not be a straight answer to the question but I thought I'd share our discussion with others facing the same decision.