Whenever I create a new JUnit Test Case it generates like this:
import junit.framework.TestCase;
public class Test extends TestCase {
}
But this isn't correct. There isn't even an #Test generated, and when I put it in myself I get a type mismatch error (cannot convert from Test to annotation). Any help?
Edit:
import static org.junit.Assert.*;
public class Test {
#org.junit.Test
public void test() {
fail("Not yet implemented");
}
}
You are not using the right version of JUnit. Check the version you are using. Annotations are available in JUnit 4 and not available in JUnit 3
Junit Test Case file Below
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestJunit {
#Test
public void testAdd() {
String str= "Junit is working fine";
assertEquals("Junit is working fine",str);
}
}
================================================================
Main Class File Below
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
Above code is working fine.
Please let me know how the main class is processing the Junit file.
I cannot understand the main class .
Please explain
It's using reflection. TestJUnit.class is the Class object representing your TestJUnit class. This object allows getting the metadata about the class: its name, its base class, its methods, annotations on the methods, etc.
So, basically, JUnitCore looks for all the public void methods without argument annotated with #Test, and executes them. If one of the method throws an unexpected exception, it's an error. If one of the methods makes an assertion fail, it's a failure, and if the method complete normally, it's a success.
I have the following sample unit test that tries to mock java.nio.file.Files but this mock does not work and the code attempts to delete the sample path.
#Test
public void testPostVisitDirectory() throws Exception {
Path mockedPath = Paths.get("sample path");
PowerMockito.mockStatic(Files.class);
PowerMockito.doNothing().when(Files.class,
PowerMockito.method(Files.class, "delete", Path.class));
DeleteDirVisitor visitor = new DeleteDirVisitor(false);
Assert.assertEquals("The was a problem visiting the file",
FileVisitResult.CONTINUE,
visitor.postVisitDirectory(mockedPath, null));
}
Any idea what is wrong?
this is the content of the method visitor.postVisitDirectory
[...]
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
[...]
Thanks,
I had a similar problem using powermock 1.5.1 and the Files class and suspect it has a problem static mocking some/all jdk1.7 classes, although I don't know why. I also checked javassist version and at the time it was latest (3.18.0-GA),
I stripped my class under test to just the Files line and it still did not work. I then decided to try to mock another static class, StringUtils.chop("string"); (commons-lang3) and then my powermock test worked and I was able to force it to generate an exception from mock.
This proved to me that I'd done everything by the book and that static mocking didn't work on Files class but it did on StringUtils.
By the way I changed, both, the #PrepareForTest and the PowerMockito.mockStatic() calls to reference the correct class.
In the end I gave up mocking Files. Just a heads-up in case anyone else has the same problem.
EDIT. Got it working: I have since tried this again as I needed it in another project. There is a newer version of PowerMock out (1.5.3) which uses an updated javassist (3.18.1-GA) that fixes a bug I mentioned in my response to another comment.
I can consistently get mocking of Files to work by adding the class under test to #PrepareForTest as well as Files now even if the class you are testing does not expose static methods. I hadn't needed to do this before for other static mocking. I don't know why it's needed or works differently for Files.
Example:
public class MyTestClass {
public void justToTestMocking(Path path) throws IOException {
if (!Files.exists(path)) {
throw new IllegalArgumentException("I know there is a deleteIfExists() but I am just testing mocking");
}
Files.delete(path);
}
}
And the test below:
#RunWith(PowerMockRunner.class)
#PrepareForTest({Files.class, MyTestClass.class})
public class MyTestClassTest {
#Before
public void setUp() {
mockStatic(Files.class);
}
#Test
public void justToTestMocking_WillDeletePath() throws IOException {
Path path = mock(Path.class);
MyTestClass test = new MyTestClass();
when(Files.exists(path)).thenReturn(true);
test.justToTestMocking(path);
verifyStatic();
Files.delete(path);
}
}
Did you add
#RunWith(PowerMockRunner.class)
#PrepareForTest(Files.class)
to your junit test class containing that method?
See powermock docs, the Writing tests section.
EDIT:
Hmmm, it seems like you're doing everything right. Here's what I'm running:
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(Files.class)
public class TestVisitor {
public class PrintingVisitor extends SimpleFileVisitor<Path> {
#Override
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
}
#Test
public void testPostVisitDirectory() throws Exception {
final Path mockedPath = Paths.get("sample path");
/* Mocking */
PowerMockito.mockStatic(Files.class);
PowerMockito.doNothing().when(Files.class, PowerMockito.method(Files.class, "delete", Path.class));
/* End Mocking */
final PrintingVisitor visitor = new PrintingVisitor();
Assert.assertEquals("The was a problem visiting the file", FileVisitResult.CONTINUE, visitor.postVisitDirectory(mockedPath, null));
}
}
If I comment out the section labeled Mocking I get the NoSuchFileException. If I leave it, the test passes.
Perhaps post complete example which produces the error?
I had a similar issue and it turns out that it was related to preparing the correct classes.
In the example above the class that was tested was already in the "prepareFor-Scope" because it was an inner class of the test class.
You have to add the classes to #PrepareForTest that call the static methods ... and in my case these was not sufficient because the code that accessed Files.deletewas inside an anonymous class that cannot be explicitly prepared.
I named the anonymous class and added it to #PrepareForTest and everything worked
I am trying to use JUnit 4.11 to set execution order.
I have tried running the Parameterized test example on this link (Changing names of parameterized tests) within Ecipse IDE and I see no change to the displayed test name in Eclipse IDE. I expect to see test names displayed like test[1: fib(1)=1] and test[4: fib(4)=3], but instead they are displayed like test[0] and test[1]
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
The following example running in Eclipse IDE results in the following execution order (b,a,d,c) instead of the expected (a,b,c,d)
package com.org;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ExecutionOrderTestName {
#Test
public void bTest() {
System.out.println("b");
}
#Test
public void aTest() {
System.out.println("a");
}
#Test
public void dTest() {
System.out.println("d");
}
#Test
public void cTest() {
System.out.println("c");
}
}
The ordering of tests is not happening, what am I doing wrong?
This sounds like you have another JUnit on the classpath. See if you have, and remove it. In Eclipse, you can look at Project Properties-> Java Build Path, then the Libraries tab.
I'm trying to preform setup and teardown for a set of integration tests, using jUnit 4.4 to execute the tests. The teardown needs to be run reliably. I'm having other problems with TestNG, so I'm looking to port back to jUnit. What hooks are available for execution before any tests are run and after all tests have completed?
Note: we're using maven 2 for our build. I've tried using maven's pre- & post-integration-test phases, but, if a test fails, maven stops and doesn't run post-integration-test, which is no help.
Yes, it is possible to reliably run set up and tear down methods before and after any tests in a test suite. Let me demonstrate in code:
package com.test;
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({Test1.class, Test2.class})
public class TestSuite {
#BeforeClass
public static void setUp() {
System.out.println("setting up");
}
#AfterClass
public static void tearDown() {
System.out.println("tearing down");
}
}
So your Test1 class would look something like:
package com.test;
import org.junit.Test;
public class Test1 {
#Test
public void test1() {
System.out.println("test1");
}
}
...and you can imagine that Test2 looks similar. If you ran TestSuite, you would get:
setting up
test1
test2
tearing down
So you can see that the set up/tear down only run before and after all tests, respectively.
The catch: this only works if you're running the test suite, and not running Test1 and Test2 as individual JUnit tests. You mentioned you're using maven, and the maven surefire plugin likes to run tests individually, and not part of a suite. In this case, I would recommend creating a superclass that each test class extends. The superclass then contains the annotated #BeforeClass and #AfterClass methods. Although not quite as clean as the above method, I think it will work for you.
As for the problem with failed tests, you can set maven.test.error.ignore so that the build continues on failed tests. This is not recommended as a continuing practice, but it should get you functioning until all of your tests pass. For more detail, see the maven surefire documentation.
A colleague of mine suggested the following: you can use a custom RunListener and implement the testRunFinished() method: http://junit.sourceforge.net/javadoc/org/junit/runner/notification/RunListener.html#testRunFinished(org.junit.runner.Result)
To register the RunListener just configure the surefire plugin as follows:
http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html section "Using custom listeners and reporters"
This configuration should also be picked by the failsafe plugin.
This solution is great because you don't have to specify Suites, lookup test classes or any of this stuff - it lets Maven to do its magic, waiting for all tests to finish.
You can use the #ClassRule annotation in JUnit 4.9+ as I described in an answer another question.
Using annotations, you can do something like this:
import org.junit.*;
import static org.junit.Assert.*;
import java.util.*;
class SomethingUnitTest {
#BeforeClass
public static void runBeforeClass()
{
}
#AfterClass
public static void runAfterClass()
{
}
#Before
public void setUp()
{
}
#After
public void tearDown()
{
}
#Test
public void testSomethingOrOther()
{
}
}
Here, we
upgraded to JUnit 4.5,
wrote annotations to tag each test class or method which needed a working service,
wrote handlers for each annotation which contained static methods to implement the setup and teardown of the service,
extended the usual Runner to locate the annotations on tests, adding the static handler methods into the test execution chain at the appropriate points.
As for "Note: we're using maven 2 for our build. I've tried using maven's pre- & post-integration-test phases, but, if a test fails, maven stops and doesn't run post-integration-test, which is no help."
you can try the failsafe-plugin instead, I think it has the facility to ensure cleanup occurs regardless of setup or intermediate stage status
Provided that all your tests may extend a "technical" class and are in the same package, you can do a little trick :
public class AbstractTest {
private static int nbTests = listClassesIn(<package>).size();
private static int curTest = 0;
#BeforeClass
public static void incCurTest() { curTest++; }
#AfterClass
public static void closeTestSuite() {
if (curTest == nbTests) { /*cleaning*/ }
}
}
public class Test1 extends AbstractTest {
#Test
public void check() {}
}
public class Test2 extends AbstractTest {
#Test
public void check() {}
}
Be aware that this solution has a lot of drawbacks :
must execute all tests of the package
must subclass a "techincal" class
you can not use #BeforeClass and #AfterClass inside subclasses
if you execute only one test in the package, cleaning is not done
...
For information: listClassesIn() => How do you find all subclasses of a given class in Java?
As far as I know there is no mechanism for doing this in JUnit, however you could try subclassing Suite and overriding the run() method with a version that does provide hooks.
Since maven-surefire-plugin does not run Suite class first but treats suite and test classes same, so we can configure plugin as below to enable only suite classes and disable all the tests. Suite will run all the tests.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<includes>
<include>**/*Suite.java</include>
</includes>
<excludes>
<exclude>**/*Test.java</exclude>
<exclude>**/*Tests.java</exclude>
</excludes>
</configuration>
</plugin>
The only way I think then to get the functionality you want would be to do something like
import junit.framework.Test;
import junit.framework.TestResult;
import junit.framework.TestSuite;
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("TestEverything");
//$JUnit-BEGIN$
suite.addTestSuite(TestOne.class);
suite.addTestSuite(TestTwo.class);
suite.addTestSuite(TestThree.class);
//$JUnit-END$
}
public static void main(String[] args)
{
AllTests test = new AllTests();
Test testCase = test.suite();
TestResult result = new TestResult();
setUp();
testCase.run(result);
tearDown();
}
public void setUp() {}
public void tearDown() {}
}
I use something like this in eclipse, so I'm not sure how portable it is outside of that environment
If you don't want to create a suite and have to list all your test classes you can use reflection to find the number of test classes dynamically and count down in a base class #AfterClass to do the tearDown only once:
public class BaseTestClass
{
private static int testClassToRun = 0;
// Counting the classes to run so that we can do the tear down only once
static {
try {
Field field = ClassLoader.class.getDeclaredField("classes");
field.setAccessible(true);
#SuppressWarnings({ "unchecked", "rawtypes" })
Vector<Class> classes = (Vector<Class>) field.get(BlockJUnit4ClassRunner.class.getClassLoader());
for (Class<?> clazz : classes) {
if (clazz.getName().endsWith("Test")) {
testClassToRun++;
}
}
} catch (Exception ignore) {
}
}
// Setup that needs to be done only once
static {
// one time set up
}
#AfterClass
public static void baseTearDown() throws Exception
{
if (--testClassToRun == 0) {
// one time clean up
}
}
}
If you prefer to use #BeforeClass instead of the static blocks, you can also use a boolean flag to do the reflection count and test setup only once at the first call. Hope this helps someone, it took me an afternoon to figure out a better way than enumerating all classes in a suite.
Now all you need to do is extend this class for all your test classes. We already had a base class to provide some common stuff for all our tests so this was the best solution for us.
Inspiration comes from this SO answer https://stackoverflow.com/a/37488620/5930242
If you don't want to extend this class everywhere, this last SO answer might do what you want.