https://www.baeldung.com/junit-assert-exception
The Matcher methods use the builder pattern so that we can combine one or more matchers to build a composite matcher chain.
@RunWith(Suite.class)
@RunWith(Parameterized.class)
hasItem(s)
starts/endsWith
containsString
Parameterized tests are used for multiple iterations over a single input to stress the object in test. The primary reason is to reduce the amount of test code.
@RunWith(Parameterized.class)
Add a method to create a dataset for factorial algorithm. The method should return Collection of the Object[] method. We need a collection of two dimensional arrays to hold the numbers and factorial values.
@Parameters
public static Collection<Object[]> factorialData() {
return Arrays.asList(new Object[][] {
{ 0, 1 }, { 1, 1 }, { 2, 2 }, { 3, 6 }, { 4, 24 }, { 5, 120 },{ 6, 720 }
});
}
@Parameter(value=0)
public int number;
@Parameter(value=1)
public int expectedResult;
@Rule
public Timeout globalTimeout = new Timeout(20);
@Rule
public ExpectedException thrown= ExpectedException.none();
thrown.expect(NullPointerException.class);
@Rule
public TemporaryFolder folder = new TemporaryFolder();
The ErrorCollector rule allows the execution of a test to continue after the first problem is found (for example, to collect all the incorrect rows in a table and report them all at once)
@Rule
public ErrorCollector collector = new ErrorCollector();
@Rule
public TestRule rule = new Verifier() {
protected void verify() {
assertNull("ErrorMsg should be null after each test execution",errorMsg);
}
};
The TestName rule makes the current test name available inside test methods. The TestName rule can be used in conjunction with the TestWatcher rule to make a unit testing framework compile a unit testing report.
public @Rule ExternalResource rule = new ExternalResource() {
@Override protected void before() throws Throwable {
resource = new Resource();
resource.open();
System.out.println(name.getMethodName());
}
@Override protected void after() {
resource.close();
System.out.println("\n");
}
};
@Rule
http://www.codeaffine.com/2012/09/24/junit-rules/
Rules provide a possibility to intercept test method calls similar as an AOP framework would do. Comparable to an around advice in AspectJ you can do useful things before and/or after the actual test execution
2) Thanks to Benny for hinting me at the System Rules library, which provides a collection of rules for testing code that uses
https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/rules/TemporaryFolder.java
https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/rules/ExternalResource.java
https://www.testwithspring.com/lesson/introduction-to-junit-4-rules/
Assume
https://github.com/junit-team/junit4/wiki/Assumptions-with-assume
https://howtodoinjava.com/best-practices/unit-testing-best-practices-junit-reference-guide/
Given/When/Then JUnit
https://github.com/alexec/givenwhenthenjunit/blob/master/src/test/java/givenwhenthenjunit/ReturnsGoToStockStoryTest.java
http://insightfullogic.com/2015/Jan/19/given-when-then-java/
http://www.tutorialspoint.com/junit/junit_extensions.htm
@Test
public
void
whenExceptionThrown_thenAssertionSucceeds() {
String test =
null
;
assertThrows(NullPointerException.
class
, () -> {
test.length();
});
}
The Matcher methods use the builder pattern so that we can combine one or more matchers to build a composite matcher chain.
@RunWith(Suite.class)
@RunWith(Parameterized.class)
hasItem(s)
starts/endsWith
containsString
Parameterized tests are used for multiple iterations over a single input to stress the object in test. The primary reason is to reduce the amount of test code.
@RunWith(Parameterized.class)
Add a method to create a dataset for factorial algorithm. The method should return Collection of the Object[] method. We need a collection of two dimensional arrays to hold the numbers and factorial values.
@Parameters
public static Collection<Object[]> factorialData() {
return Arrays.asList(new Object[][] {
{ 0, 1 }, { 1, 1 }, { 2, 2 }, { 3, 6 }, { 4, 24 }, { 5, 120 },{ 6, 720 }
});
}
@Parameter(value=0)
public int number;
@Parameter(value=1)
public int expectedResult;
@Rule
public Timeout globalTimeout = new Timeout(20);
@Rule
public ExpectedException thrown= ExpectedException.none();
thrown.expect(NullPointerException.class);
@Rule
public TemporaryFolder folder = new TemporaryFolder();
The ErrorCollector rule allows the execution of a test to continue after the first problem is found (for example, to collect all the incorrect rows in a table and report them all at once)
@Rule
public ErrorCollector collector = new ErrorCollector();
@Rule
public TestRule rule = new Verifier() {
protected void verify() {
assertNull("ErrorMsg should be null after each test execution",errorMsg);
}
};
The TestName rule makes the current test name available inside test methods. The TestName rule can be used in conjunction with the TestWatcher rule to make a unit testing framework compile a unit testing report.
public @Rule ExternalResource rule = new ExternalResource() {
@Override protected void before() throws Throwable {
resource = new Resource();
resource.open();
System.out.println(name.getMethodName());
}
@Override protected void after() {
resource.close();
System.out.println("\n");
}
};
@Rule
http://www.codeaffine.com/2012/09/24/junit-rules/
Rules provide a possibility to intercept test method calls similar as an AOP framework would do. Comparable to an around advice in AspectJ you can do useful things before and/or after the actual test execution
The API part of a rule definition has to implement TestRule. The only method of this interface called
apply
returns a Statement
. Statement
s represent – simply spoken – your tests within the JUnit runtime and Statement#evaluate()
executes them. Now the basic idea is to provide wrapper extensions of Statement
that can do the actual contributions by overriding Statement#evaluate()
:java.lang.System
.https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/rules/TemporaryFolder.java
https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/rules/ExternalResource.java
https://www.testwithspring.com/lesson/introduction-to-junit-4-rules/
If we need to create files and/or folders that are deleted after a test method has finished, we have to use the
TemporaryFolder
rule. We can enable this rule by adding a public TemporaryFolder
field into our test class and annotating that field with the @Rule
annotation.
We can now create files and folders by using the
TemporaryFolder
rule.
The
TemporaryFolder
rule does not ensure that the files and folders were deleted successfully. If we are using JUnit 4.13 or newer, we can configure the TemporaryFolder
rule to throw an AssertionError
if the files and folders cannot be deleted.
If we want to enable this feature, we have to create the
TemporaryFolder
field by using the following code:
1
2
3
4
| @Rule public TemporaryFolder folder = TemporaryFolder.builder() .assureDeletion() .build(); |
- A JUnit rule is a component that intercepts test method calls and allows us to do something before the test method is invoked and after the test method has been invoked.
- JUnit 4 requires that rule fields are annotated with the
@Rule
annotation, arepublic
, are notstatic
, and are subtype ofTestRule
. - The
TemporaryFolder
rule allows us to create files and/or folders that are deleted after a test method has finished.
@Rule public final TemporaryFolder tempFolder = new TemporaryFolder(); @Rule public final ExpectedException exception = ExpectedException.none();
- The ErrorCollector Rule allows execution of a test to continue after the first problem is found (for example, to collect all the incorrect rows in a table, and report them all at once):
- The Timeout Rule applies the same timeout to all test methods in a class:
- The TestName Rule makes the current test name available inside test methods:
Rules are used to add additional functionality which applies to all tests within a test class, but in a more generic way.
For instance, ExternalResource executes code before and after a test method, without having to use
@Before
and @After
. Using an ExternalResource
rather than @Before
and @After
gives opportunities for better code reuse; the same rule can be used from two different test classes.Assume
https://github.com/junit-team/junit4/wiki/Assumptions-with-assume
assumeTrue
means that the test shouldn't run. It does not mean your code is broken and most runners will treat this test as "ignored"
In this post, I am writing about writing junit testcases which will run only when a certain condition is met on runtime. For example, I want to run a testcase only when some other network service is up. I do not want to fail my test, if service is down.
In junit, above is possible with use of “org.junit.Assume“.
String versionNumber = "7"; //Get it from configuration on runtime Assume.assumeTrue(Integer.valueOf(versionNumber) == 7);
If you want to ignore all testcases in a single java class then it can be used in @Before annotated method. All testcases will be ignored in such way.
@Before public void setUp() { String versionNumber = "7"; //Get it from configuration on runtime Assume.assumeTrue(Integer.valueOf(versionNumber) == 7); }
- Running testcases for specific application version(s)
- Running testcases only when certain network resource (or any external service) is available
- Running testcases in a certain locale only
- Running testcases only under certain execution environment
Name your unit tests clearly and consistently
You must name your testcases on what they actually do and test. Testcase naming convention which uses class names and method names for testcases name, is never a good idea. Every time you change the method name or class name, you will end up updating a lot of test cases as well.
But, if your test cases names are logical i.e. based on operations then you will need almost no modification because most possibly application logic will remain same.
E.g. Test case names should be like:
1) TestCreateEmployee_NullId_ShouldThrowException
2) TestCreateEmployee_NegativeId_ShouldThrowException
3) TestCreateEmployee_DuplicateId_ShouldThrowException
4) TestCreateEmployee_ValidId_ShouldPass
2) TestCreateEmployee_NegativeId_ShouldThrowException
3) TestCreateEmployee_DuplicateId_ShouldThrowException
4) TestCreateEmployee_ValidId_ShouldPass
Test only one code unit at a time Don’t make unnecessary assertions Make each test independent to all the others Mock out all external services and state Don’t unit-test configuration settings Name your unit tests clearly and consistently Write tests for methods that have the fewest dependencies first, and work your way up All methods, regardless of visibility, should have appropriate unit tests Aim for each unit test method to perform exactly one assertion Create unit tests that target exceptions Use the most appropriate assertion methods. Put assertion parameters in the proper order Ensure that test code is separated from production code Do not print anything out in unit tests Do not use static members in a test class Do not write your own catch blocks that exist only to fail a test Do not rely on indirect testing Integrate Testcases with build script Do not skip unit tests Capture results using the XML formatter
Given/When/Then JUnit
https://github.com/alexec/givenwhenthenjunit/blob/master/src/test/java/givenwhenthenjunit/ReturnsGoToStockStoryTest.java
http://insightfullogic.com/2015/Jan/19/given-when-then-java/
http://www.tutorialspoint.com/junit/junit_extensions.htm
Cactus is a simple test framework for unit testing server-side java code (Servlets, EJBs, Tag Libs, Filters). The intent of Cactus is to lower the cost of writing tests for server-side code. It uses JUnit and extends it. Cactus implements an in-container strategy, meaning that tests are executed inside the container.
http://blog.goyello.com/2015/10/01/different-ways-of-testing-exceptions-in-java-and-junit/
cleanup methods:
In JUnit 3 and in JUnit 4 − before
The simplest way to verify exceptions in JUnit (4+) tests, that requires (almost) no additional code, comes withExpectedException
rule was introduced − the best way to test exceptions was by using standard classical try-catch
idiom in a unit test:@Test
annotation and expected
element
private Thrower thrower = new Thrower();
@Test(expected = MyRuntimeException.class)
public void throwsException() { // will pass
thrower.throwsRuntime();
System.out.println("I am here!"); // never gets executed
}
@Test(expected = MyCheckedException.class) // will fail
public void throwsDifferentExceptionThanExpected() throws MyCheckedException {
thrower.throwsRuntimeInsteadOfChecked();
}
@Test(expected = MyRuntimeException.class)
public void noExceptionThrown() { // will fail
}
@Test(expected = RuntimeException.class)
public void misleading() { // will pass
thrower.throwsRuntime(); // assume this is an unexpected exception
throw new RuntimeException(); // never executed!
}
In JUnit, rules (@Rule
) can be used as an alternative or an addition to fixture setup and cleanup methods:
@Before
, @After
, @BeforeClass
, and @AfterClass
. ExpectedException
rule is meant for verification that code throws a specific exception. The rule must be declared as public field annotated with @Rule
annotation:
@Rule
public ExpectedException thrown = ExpectedException.none();
thrown.expect(MyRuntimeException.class);
thrown.expectMessage("My custom runtime exception");
thrower.throwsRuntime();
What is more,the ExpectedException
rule provide us methods to verify exceptions in a more sophisticated way using Hamcrest matchers. Hamcrest provides a library of matcher objects and it works great with JUnit
thrown.expect(RuntimeException.class);
thrown.expectMessage(startsWith("My custom runtime"));