I know that one way to do it would be:
#Test
public void foo() {
try {
// execute code that you expect not to throw Exceptions.
} catch(Exception e) {
fail("Should not have thrown any exception");
}
}
Is there any cleaner way of doing this? (Probably using Junit's #Rule?)
You're approaching this the wrong way. Just test your functionality: if an exception is thrown the test will automatically fail. If no exception is thrown, your tests will all turn up green.
I have noticed this question garners interest from time to time so I'll expand a little.
Background to unit testing
When you're unit testing it's important to define to yourself what you consider a unit of work. Basically: an extraction of your codebase that may or may not include multiple methods or classes that represents a single piece of functionality.
Or, as defined in The art of Unit Testing, 2nd Edition by Roy Osherove, page 11:
A unit test is an automated piece of code that invokes the unit of work being tested, and then checks some assumptions about a single end result of that unit. A unit test is almost always written using a unit testing framework. It can be written easily and runs quickly. It's trustworthy, readable, and maintainable. It's consistent in its results as long as production code hasn't changed.
What is important to realize is that one unit of work usually isn't just one method but at the very basic level it is one method and after that it is encapsulated by other unit of works.
Ideally you should have a test method for each separate unit of work so you can always immediately view where things are going wrong. In this example there is a basic method called getUserById() which will return a user and there is a total of 3 unit of works.
The first unit of work should test whether or not a valid user is being returned in the case of valid and invalid input.
Any exceptions that are being thrown by the datasource have to be handled here: if no user is present there should be a test that demonstrates that an exception is thrown when the user can't be found. A sample of this could be the IllegalArgumentException which is caught with the #Test(expected = IllegalArgumentException.class) annotation.
Once you have handled all your usecases for this basic unit of work, you move up a level. Here you do exactly the same, but you only handle the exceptions that come from the level right below the current one. This keeps your testing code well structured and allows you to quickly run through the architecture to find where things go wrong, instead of having to hop all over the place.
Handling a tests' valid and faulty input
At this point it should be clear how we're going to handle these exceptions. There are 2 types of input: valid input and faulty input (the input is valid in the strict sense, but it's not correct).
When you work with valid input you're setting the implicit expectancy that whatever test you write, will work.
Such a method call can look like this: existingUserById_ShouldReturn_UserObject. If this method fails (e.g.: an exception is thrown) then you know something went wrong and you can start digging.
By adding another test (nonExistingUserById_ShouldThrow_IllegalArgumentException) that uses the faulty input and expects an exception you can see whether your method does what it is supposed to do with wrong input.
TL;DR
You were trying to do two things in your test: check for valid and faulty input. By splitting this into two method that each do one thing, you will have much clearer tests and a much better overview of where things go wrong.
By keeping the layered unit of works in mind you can also reduce the amount of tests you need for a layer that is higher in the hierarchy because you don't have to account for every thing that might have gone wrong in the lower layers: the layers below the current one are a virtual guarantee that your dependencies work and if something goes wrong, it's in your current layer (assuming the lower layers don't throw any errors themselves).
JUnit 5 (Jupiter) provides three functions to check exception absence/presence:
● assertAll()
Asserts that all supplied executables
do not throw exceptions.
● assertDoesNotThrow()
Asserts that execution of the
supplied executable/supplier
does not throw any kind of exception.
This function is available
since JUnit 5.2.0 (29 April 2018).
● assertThrows()
Asserts that execution of the supplied executable
throws an exception of the expectedType
and returns the exception.
Example
package test.mycompany.myapp.mymodule;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class MyClassTest {
#Test
void when_string_has_been_constructed_then_myFunction_does_not_throw() {
String myString = "this string has been constructed";
assertAll(() -> MyClass.myFunction(myString));
}
#Test
void when_string_has_been_constructed_then_myFunction_does_not_throw__junit_v520() {
String myString = "this string has been constructed";
assertDoesNotThrow(() -> MyClass.myFunction(myString));
}
#Test
void when_string_is_null_then_myFunction_throws_IllegalArgumentException() {
String myString = null;
assertThrows(
IllegalArgumentException.class,
() -> MyClass.myFunction(myString));
}
}
I stumbled upon this because of SonarQube's rule "squid:S2699": "Add at least one assertion to this test case."
I had a simple test whose only goal was to go through without throwing exceptions.
Consider this simple code:
public class Printer {
public static void printLine(final String line) {
System.out.println(line);
}
}
What kind of assertion can be added to test this method?
Sure, you can make a try-catch around it, but that is only code bloat.
The solution comes from JUnit itself.
In case no exception is thrown and you want to explicitly illustrate this behaviour, simply add expected as in the following example:
#Test(expected = Test.None.class /* no exception expected */)
public void test_printLine() {
Printer.printLine("line");
}
Test.None.class is the default for the expected value.
If you import org.junit.Test.None, you can then write:
#Test(expected = None.class)
which you might find more readable.
For JUnit versions before 5:
With AssertJ fluent assertions 3.7.0:
Assertions.assertThatCode(() -> toTest.method())
.doesNotThrowAnyException();
Update:
JUnit 5 introduced assertDoesNotThrow() assertion, so I'd prefer to use it instead of adding an additional dependency to your project. See this answer for details.
Java 8 makes this a lot easier, and Kotlin/Scala doubly so.
We can write a little utility class
class MyAssertions{
public static void assertDoesNotThrow(FailingRunnable action){
try{
action.run()
}
catch(Exception ex){
throw new Error("expected action not to throw, but it did!", ex)
}
}
}
#FunctionalInterface interface FailingRunnable { void run() throws Exception }
and then your code becomes simply:
#Test
public void foo(){
MyAssertions.assertDoesNotThrow(() -> {
//execute code that you expect not to throw Exceptions.
}
}
If you dont have access to Java-8, I would use a painfully old java facility: aribitrary code blocks and a simple comment
//setup
Component component = new Component();
//act
configure(component);
//assert
/*assert does not throw*/{
component.doSomething();
}
And finally, with kotlin, a language I've recently fallen in love with:
fun (() -> Any?).shouldNotThrow()
= try { invoke() } catch (ex : Exception){ throw Error("expected not to throw!", ex) }
#Test fun `when foo happens should not throw`(){
//...
{ /*code that shouldn't throw*/ }.shouldNotThrow()
}
Though there is a lot of room to fiddle with exactly how you want to express this, I was always a fan of fluent assertions.
Regarding
You're approaching this the wrong way. Just test your functionality: if an exception is thrown the test will automatically fail. If no exception is thrown, your tests will all turn up green.
This is correct in principle but incorrect in conclusion.
Java allows exceptions for flow of control. This is done by the JRE runtime itself in APIs like Double.parseDouble via a NumberFormatException and Paths.get via a InvalidPathException.
Given you've written a component that validates Number strings for Double.ParseDouble, maybe using a Regex, maybe a hand-written parser, or perhaps something that embeds some other domain rules that restricts the range of a double to something specific, how best to test this component? I think an obvious test would be to assert that, when the resulting string is parsed, no exception is thrown. I would write that test using either the above assertDoesNotThrow or /*comment*/{code} block. Something like
#Test public void given_validator_accepts_string_result_should_be_interpretable_by_doubleParseDouble(){
//setup
String input = "12.34E+26" //a string double with domain significance
//act
boolean isValid = component.validate(input)
//assert -- using the library 'assertJ', my personal favourite
assertThat(isValid).describedAs(input + " was considered valid by component").isTrue();
assertDoesNotThrow(() -> Double.parseDouble(input));
}
I would also encourage you to parameterize this test on input using Theories or Parameterized so that you can more easily re-use this test for other inputs. Alternatively, if you want to go exotic, you could go for a test-generation tool (and this). TestNG has better support for parameterized tests.
What I find particularly disagreeable is the recommendation of using #Test(expectedException=IllegalArgumentException.class), this exception is dangerously broad. If your code changes such that the component under test's constructor has if(constructorArgument <= 0) throw IllegalArgumentException(), and your test was supplying 0 for that argument because it was convenient --and this is very common, because good generating test data is a surprisingly hard problem--, then your test will be green-bar even though it tests nothing. Such a test is worse than useless.
If you are unlucky enough to catch all errors in your code.
You can stupidly do
class DumpTest {
Exception ex;
#Test
public void testWhatEver() {
try {
thisShouldThrowError();
} catch (Exception e) {
ex = e;
}
assertEquals(null,ex);
}
}
Although this post is 6 years old now, however, a lot has changed in the Junit world. With Junit5, you can now use
org.junit.jupiter.api.Assertions.assertDoesNotThrow()
Ex:
public void thisMethodDoesNotThrowException(){
System.out.println("Hello There");
}
#Test
public void test_thisMethodDoesNotThrowException(){
org.junit.jupiter.api.Assertions.assertDoesNotThrow(
()-> thisMethodDoesNotThrowException()
);
}
Hope it will help people who are using newer version of Junit5
JUnit5 adds the assertAll() method for this exact purpose.
assertAll( () -> foo() )
source: JUnit 5 API
To test a scenario with a void method like
void testMeWell() throws SomeException {..}
to not throw an exception:
Junit5
assertDoesNotThrow(() -> {
testMeWell();
});
If you want to test that whether your test target consumes the exception. Just leave the test as (mock collaborator using jMock2):
#Test
public void consumesAndLogsExceptions() throws Exception {
context.checking(new Expectations() {
{
oneOf(collaborator).doSth();
will(throwException(new NullPointerException()));
}
});
target.doSth();
}
The test would pass if your target does consume the exception thrown, otherwise the test would fail.
If you want to test your exception consumption logic, things get more complex. I suggest delegating the consumption to a collaborator which could be mocked. Therefore the test could be:
#Test
public void consumesAndLogsExceptions() throws Exception {
Exception e = new NullPointerException();
context.checking(new Expectations() {
{
allowing(collaborator).doSth();
will(throwException(e));
oneOf(consumer).consume(e);
}
});
target.doSth();
}
But sometimes it's over-designed if you just want to log it. In this case, this article(http://java.dzone.com/articles/monitoring-declarative-transac, http://blog.novoj.net/2008/09/20/testing-aspect-pointcuts-is-there-an-easy-way/) may help if you insist tdd in this case.
Use assertNull(...)
#Test
public void foo() {
try {
//execute code that you expect not to throw Exceptions.
} catch (Exception e){
assertNull(e);
}
}
This may not be the best way but it definitely makes sure that exception is not thrown from the code block that is being tested.
import org.assertj.core.api.Assertions;
import org.junit.Test;
public class AssertionExample {
#Test
public void testNoException(){
assertNoException();
}
private void assertException(){
Assertions.assertThatThrownBy(this::doNotThrowException).isInstanceOf(Exception.class);
}
private void assertNoException(){
Assertions.assertThatThrownBy(() -> assertException()).isInstanceOf(AssertionError.class);
}
private void doNotThrowException(){
//This method will never throw exception
}
}
I faced the same situation, I needed to check that exception is thrown when it should, and only when it should.
Ended up using the exception handler to my benefit with the following code:
try {
functionThatMightThrowException()
}catch (Exception e){
Assert.fail("should not throw exception");
}
RestOfAssertions();
The main benefit for me was that it is quite straight forward and to check the other way of the "if and only if" is really easy in this same structure
I end up doing like this
#Test
fun `Should not throw`() {
whenever(authService.isAdmin()).thenReturn(true)
assertDoesNotThrow {
service.throwIfNotAllowed("client")
}
}
You can expect that exception is not thrown by creating a rule.
#Rule
public ExpectedException expectedException = ExpectedException.none();
You can do it by using a #Rule and then call method reportMissingExceptionWithMessage as shown below:
This is Scala code.
Stumbled over this issue since I created some generic methods like
#Test
void testSomething() {
checkGeneric(anComplexObect)
}
In https://newbedev.com/sonarqube-issue-add-at-least-one-assertion-to-this-test-case-for-unit-test-with-assertions some annotation stuff is proposed.
The solution is much more simple. It's enough to rename the "checkGeneric" method to "assertGeneric".
#Test
void testSomething() {
assertGeneric(anComplexObect)
}
You can create any kind of your own assertions based on assertions from junit, because these are especially designed for creating user defined asserts intendet to work exactly like junit ones:
static void assertDoesNotThrow(Executable executable) {
assertDoesNotThrow(executable, "must not throw");
}
static void assertDoesNotThrow(Executable executable, String message) {
try {
executable.execute();
} catch (Throwable err) {
fail(message);
}
}
Now testing the so called scenario methodMustNotThrow and log all failures in a junit style:
//test and log with default and custom messages
//the following will succeed
assertDoesNotThrow(()->methodMustNotThrow(1));
assertDoesNotThrow(()->methodMustNotThrow(1), "custom facepalm");
//the following will fail
assertDoesNotThrow(()->methodMustNotThrow(2));
assertDoesNotThrow(()-> {throw new Exception("Hello world");}, "message");
//See implementation of methodMustNotThrow below
Generally speaking there is possibility to instantly fail anything the test in any scenarios, in any place where it makes sense by calling fail(someMessage), which is designed exactly for this purpose. For instance use it in a try/catch block to fail if anything is thrown in the test case:
try{methodMustNotThrow(1);}catch(Throwable e){fail("must not throw");}
try{methodMustNotThrow(1);}catch(Throwable e){Assertions.fail("must not throw");}
This is the sample of the method we test, supposing we have such a method that must not fail under specific circumstances, but it can fail:
void methodMustNotThrow(int x) throws Exception {
if (x == 1) return;
throw new Exception();
}
The above method is a simple sample. But this works for complex situations, where the failure is not so obvious.
There are the imports:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.junit.jupiter.api.Assertions.*;
AssertJ can handle this scenario:
assertThatNoException().isThrownBy(() -> System.out.println("OK"));
Check the doc for more information https://assertj.github.io/doc/#assertj-core-exception-assertions-no-exception
The following fails the test for all exceptions, checked or unchecked:
#Test
public void testMyCode() {
try {
runMyTestCode();
} catch (Throwable t) {
throw new Error("fail!");
}
}
I've got a class that looks like this:
public class Foo {
public meth() {
try {
privMethod();
System.out.println("Yay!");
} catch (FooException e) {
System.out.println("Boo!");
}
}
private void privMethod() throws FooException {
//doOtherStuff
if (someCondition()) {
throw new FooException();
}
}
private class FooException extends Exception {
FooException(String message) { super(message); }
}
}
I want to write a unit test for this, using Mockito and Powermock. I know I can mock the private method like this:
Foo spy = PowerMockito.spy(new Foo())
PowerMockito.doNothing().when(spy, "privMethod");
But how do I tell it to throw the exception? I know it'll be something like this:
Powermockito.doThrow(/*what goes here?*/).when(spy, "privMethod");
What goes there?
Note that the exception is a private inner class, so I can't just do doThrow(new FooException()), since FooException isn't accessible from the unit test.
In general, you go.
Powermockito.doThrow(theThingToThrow)
goes there. Like doThrow(new RuntimeException("should be thrown")) for example. Or a more specific exception, depending what you want the code under test to do about the exception.
But of course: you want to instantiate a private class there. Which you can't do (easily, see here for terribly complicated ways to do that). From that point of view: you created a very-hard-to-test design. The answer is to rework that design, making it easier to test.
And a final word of warning: I think you should not need to use PowerMockito for this. Spies work with plain Mockito.
And when there is no hard need to use the PowerMock(ito) versions, then do not use them. Period. They have their place, but honestly: most often, needing PowerMock(ito) equals to "hard to test code".
Beyond that: looking at private methods translates to testing implementation details. And that is also something to avoid when possible.
So, in other words: A) it is close to impossible to test the above code in meaningful ways. B) It would also be bad practice to do so (as envisioned in the question). Therefore the "best" solution here is to step back and re-design the whole thing. Yes, I am serious.
I'm having issues with SonarQube raising issues with several of my unit tests, prompting the following issue:
Add at least one assertion to this test case.
Each test case resembles this format (where a number of assertions are delegated to a method with common assertions, to avoid duplication):
#Test
public void companyNameOneTooLong() throws Exception {
AddressFormBean formBean = getValidBean();
formBean.setCompanyNameOne("123456789012345678901234567890123456");
assertViolation(validator.validate(formBean), "companyNameOne", "length must be between 0 and 35");
}
private void assertViolation(Set<ConstraintViolation<AddressFormBean>> violations, String fieldname, String message) {
assertThat(violations, hasSize(1));
assertEquals(fieldname, violations.iterator().next().getPropertyPath().iterator().next().getName());
assertEquals(message, violations.iterator().next().getMessage());
}
Now, obviously I could just pull the three assertions out of the private method and put them in the test method - but I'm performing the same checks (on different fields) multiple times.
So, I thought I'd try to emulate the behaviour of the assertion methods, by (re) throwing an AssertionError:
private void assertViolation(Set<ConstraintViolation<AddressFormBean>> violations, String fieldname, String message) throws AssertionError {
try {
assertThat(violations, hasSize(1));
assertEquals(fieldname, violations.iterator().next().getPropertyPath().iterator().next().getName());
assertEquals(message, violations.iterator().next().getMessage());
} catch (AssertionError e) {
throw e;
}
}
Unfortunately, this approach does not work either.
What's special about the JUnit assert methods / what is SonarQube looking for specifically to check that an assertion has been made for each test?
Alternatively - are there other approaches to achieve the same end result (avoiding duplicating the shared assertion code over and over)?
The rule S2699 (Tests should include assertions) from the SonarQube Java Analyzer does not perform cross-procedural analysis and only explore body of methods being identified as test method (usually annotated with #Test).
Consequently, if the only assertions which will be called when executing the test method are done by a dedicated method (to avoid duplication), then the rule will raise an issue. This is a known limitation of the rule and we will deal with it only when we will be able to efficiently perform cross-procedural analysis.
Regarding the issues raised by SonarQube on such cases, you can safely mark them as Won't Fix.
Regarding the detected assertions, the rule consider as assertions the usual assert/fail/verify/expect methods from the following (unit test) frameworks :
JUnit
Fest (1.x & 2.x)
AssertJ
Hamcrest
Mockito
Spring
EasyMock
If you don't expect any exception to be throw from your test, this can be a workaround:
#Test(expected = Test.None.class /* no exception expected */)
Alternatively, you can suppress the warning for the test method/test class:
#SuppressWarnings("squid:S2699")
One thing I have done in the past is to have the helper method return true, and assert on that:
#Test
public void testSomeThings() {
Thing expected = // . . .
Thing actual = service.methodReturningThing(42);
assertTrue(assertViolation(expected, actual));
}
private boolean assertViolation(Thing expected, Thing actual) {
assertEquals(expected.getName(), actual.getName());
assertEquals(expected.getQuest(), actual.getQuest());
assertEquals(expected.getFavoriteColor(), actual.getFavoriteColor());
return true;
}
I hate this, but I hate duplicated code even more.
The other thing we've done at times, is to simply mark any such objections from SonarQube as Won't Fix, but I hate that, too.
Sometimes you don't need to have any code or assertation, for example, the test of load the context of spring boot successfully. In this case, to prevent Sonar issue when you don't expect any exception to be throw from your test, you can use this part of the code:
#Test
void contextLoads() {
Assertions.assertDoesNotThrow(this::doNotThrowException);
}
private void doNotThrowException(){
//This method will never throw exception
}
I'm creating an integration test:
#RunWith(CdiRunner.class)
#AdditionalClasses({FollowUpActivityRepository.class, SettingsPropertiesProducer.class})
public class FollowUpActivityFeaturesTest {
#Inject protected FollowUpActivityService fuaService;
#Test
public void DigitalInputTOFollowUpActivityFIELDS()
{
FollowUpActivityDTO dto = new FollowUpActivityDTO();
dto.setId("id");
dto.setTimestamp(Date.from(Instant.now()));
dto.setDueTimestamp(Date.from(Instant.now()));
dto.setClosingTimestamp(Date.from(Instant.now()));
dto.setMatter("matter");
dto.setComment("comment");
this.fuaService.createOrUpdate(dto);
}
}
createOrUpdate is like:
public void createOrUpdate(FollowUpActivityDTO dto) throws RepositorySystemException
So, I need to check this exception is NOT thrown.
I'd like to do it elegantly.
Actually, I'm using junit 4.12 and hamcrest 2.0.0.0.
Any ideas?
Example
In .NET, I'm using NSubstitute in order to get that:
this.apiClient.Invoking(c => c.GrantAuthorization()).ShouldNotThrow();
Edit after you reversed the meaning of the question:
If you want your test to fail if an Exception is thrown, you have nothing more to do than just declare an Exception in the throws part of the test method signature (this is not mandatory if the Exception thrown is some kind of RuntimeException, but yours obviously isn't):
public void DigitalInputTOFollowUpActivityFIELDS() throws Exception
No need to specify any kind of Exception. Anyway, any jUnit test will fail as soon as an unhandled Exception is thrown (which is the behavior you're expecting).
From this blog:
Test methods that declare that they throw one particular type of
exception are brittle because they must be changed whenever the method
under test changes.
Old answer:
Just write your test annotation like this:
#Test(expected=RepositorySystemException.class)
This way, the test method will succeed as soon as this exception is thrown.
See javadoc.
Edit after your comment:
To validate the test against any Exception, just:
#Test(expected=Exception.class)
But as B. Dalton suggested, that seems kind of dangerous, as this test would then pass on any Exception, no matter if it's the one you're expecting or any other.
For the sake of completeness, you can also do something like this (based on this answer):
#Rule
public ExpectedException thrown = ExpectedException.none();
#Test
public void DigitalInputTOFollowUpActivityFIELDS()
{
FollowUpActivityDTO dto = new FollowUpActivityDTO();
dto.setId("id");
dto.setTimestamp(Date.from(Instant.now()));
dto.setDueTimestamp(Date.from(Instant.now()));
dto.setClosingTimestamp(Date.from(Instant.now()));
dto.setMatter("matter");
dto.setComment("comment");
thrown.expect(Exception.class);
thrown.expectMessage("something you can check"); // if needed
this.fuaService.createOrUpdate(dto);
}
This way, createOrUpdate will still be able to validate the test by throwing any kind of Exception, but at least the rest of the method won't.
See javadoc for ExpectedException.
Or, of course, the good old solution:
try {
this.fuaService.createOrUpdate(dto);
fail("this should throw an exception");
} catch (RepositorySystemException e){
// pass
} catch (Exception e){
// pass
}
This is less elegant, but allows you to tweak the exception handling as you need.
I have a series of data each one containing info_A and info_B. I would like to:
if(info_A) {
run Test A
} else if(!info_A) {
run Test B
}
It is very important that only the Test actually run is shown in the JUnit GUI tree. How can I do this?
The following solutions do not work:
If I use the Assume.assumeTrue(conditon), I can Ignore a test but then it is still displayed as passed in the test.
Doing this:
Result result = JUnitCore.runClasses(TestStep1.class);
leads to the correct result but the JUnit tree is not built.
Using #Catagories also shows the failed tests, which is also what I don't want.
You can use Assume to turn tests on/off conditionally:
A set of methods useful for stating assumptions about the conditions in which a test is meaningful. A failed assumption does not mean the code is broken, but that the test provides no useful information.
You can do this with JUnit Rules.
There's a whole blog post dedicated to exactly your question here, but in short, you do the following:
Create a class that implements the org.junit.rules.TestRule interface. This interface contains the following method:
Statement apply(Statement base, Description description);
The base argument is actually your test, which you run by calling base.execute() -- well, the apply() method actually returns a Statement anonymous instance that will do that. In your anonymous Statement instance, you'll add the logic to determine whether or not the test should be run. See below for an example of a TestRule implementation that doesn't do anything except execute your test -- and yes, it's not particularly straighforward.
Once you've created your TestRule implementation, then you need to add the following lines to to your JUnit Test Class:
#Rule
public MyTestRuleImpl conditionalTests;
Remember, the field must be public.
And that's it. Good luck -- as I said, you may have to hack a little, but I believe there's a fair amount explained in the blog post. Otherwise, there should be other information on the internets (or in the JUnit sourc code).
Here's a quick example of a TestRule implementation that doesn't do anything.
public abstract class SimpleRule implements TestRule {
public Statement apply(final Statement base, final Description description) {
return new Statement() {
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (Throwable t) {
t.printStackTrace();
}
}
};
}
}