Pre-condition: VM param -ea is enabled
Example in source code:
assert booleanVariable;
which will throw AssertionError if the booleanVariable is false.
I wrote JUnit tests which results in FALSE booleanVariable, so how to catch the error instead of halted JUnit tests without using plugins. Note that the application functions as a threaded module. Therefore, JUnit tests calls a generic postMessage method like below:
#Test
public void myTest(){
Message invalidMessage = new Message("I am invalid");
//somewhere in threadedModule source code would throw AssertionError
//after reading from its inputQueue
threadedModule.postMessage(invalidMessage );
assertNotNull(onputQueue.waitForNextMessage(timeOutTime,timeOutMessage));
}
Thank you!
This cannot be achieved because threaded module you created is running on a thread separate from JUnit test thread. The try catch block can only catch throwable inside its own thread.
Related
I working on testing some static classes using PowerMockito, and sometimes the test fail, in order to overcame this issue a create a customize JUnit Rule to re-run the failure tests. The rule works fine but whenever the test is re-executed , it's fail again but this time at the instruction mockStatic(StaticClass.class) which throw the exception org.powermock.api.mockito.ClassNotPreparedException.
Why the #PrepareForTest is executed only at the first run but not when the test is re-run.
I think the problem was caused by PowerMock when he creat a deep clone of my rules. To overcome this problem I used JUnit rule chain :
RuleChain.outerRule((base, description) -> {
try {
final FrameworkMethod method = new FrameworkMethod(
description.getTestClass().getMethod(description.getMethodName()));
return (new PowerMockRule()).apply(base, method, this);
} catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException(e);
}
}).around(myRetryRule).around(otherRules).....
A more generale soulution for this problem is proposed here MergedRule, 2, 3.
I am getting InvalidUseOfMatchersException on a different test than the one using Matchers
The below two tests are running fine individually but when running together, after the first test passes successfully, second test is failing and throwing InvalidUseOfMatchersException pointing to first test
#Test(expected = InputException.class)
public void shouldThrowExceptionWhenInputNull() {
calculator.calculateA(any(), any(), any(),eq(null));
}
#Test
public void testCalculateB() {
assertTrue(BigDecimal.valueOf(8000).compareTo(calculator.calculateB(12)) == 0);
}
This is the exception in stack trace
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
TestClass.shouldThrowExceptionWhenInputNull
According to the exception, first test should fail but its passing and second test is failing. Individually both these tests are passing successfully
calculator.calculateA(any(), any(), any(), eq(null));
This isn't a valid use of Matchers. Mockito only uses any and eq when used with when or verify, as a means of matching invocations that tell Mockito what to return or what calls should have been recorded. You'll need to call calculateA with specific values, such as calculator.calculateA(1, 2, 3, null);.
Mockito matchers work via side effects, so the only time that Mockito can throw an exception is the next time you interact with Mockito. This might be another method, but you can help ensure that those are local by using MockitoRule, MockitoJUnitRunner, or by adding a call to validateMockitoUsage from an #After method:
#After public void validateMockito() {
Mockito.validateMockitoUsage();
}
How do I test if an assertion is thrown by the method under test using junit? Heres the method I'm testing:
public int f(int i){
assert i > 0;
return i;
}
I'm using junit 4.12.
You can test it by providing parameter in #Test annotation:
#Test(expected = AssertionError.class)
public void shouldThrowExceptionWhenIncorrectInput() {
f(-3);
}
This will check if the AssertException is thrown.
However, if you want to ensure that this function wont be run with incorrect parameters, you have to be aware that assertions can be turned off by running java with -da parameters.
To ensure that exception is thrown I would suggest throwing IllegalArgumentException inside some validation method, and to provide it with proper message. Then you will be sure that this will always throw exception when incorrect parameters are provided.
I have this scenario in which some tests can throw different exceptions.
#Test
public void addDevice(){
device.addDevice(); // this may throw exception 1
device.verifyStatus("Ready");
device.open(); // this may throw exception 2
device.verifyStatus("Open");
}
#Test
public void otherTest(){
device.act(); // this may throw exception 3
device.verifyStatus("Ready");
}
#After
public void tearDown(){
// handle the exception here
}
I want to handle those exceptions in the #After section without wrapping the test with try, catch.
Is that possible?
No, it is not possible.
You could wrap the test anyway with a try-catch-block. Then you could store the exception to a member variable instead of handling it.
In the #After method you can check whether the exception is null or not.
Due to your comment that you have hundreds of tests with this code I assume that this is set up logic which should actually be in an #Before method.
Thus, you could specify an external resource rule with a before and after method: https://github.com/junit-team/junit/wiki/Rules#externalresource-rules
In the before() method you perform the set up, catch and store the exceptions and in the after() method you handle them.
But does it make sense to handle the exception later? Can you run your test cases successfully if the set up fails?
In my webdriver script I have the three methods
setup, test and tearDown
following the junit convention.
In the test method I have few asserts like this
#Test
public void testStudentHome() throws Exception {
String classCode = "I6OWW";
Utilities.studentSignin(driver, baseUrl);
assertEquals(true, sth.openNotification());
assertEquals("My Scores", sth.myScores(true));
}
The sth is the PageObject on which I am performing the tests and that I have created in the setup method.
I am calling all these three methods from a main method like this:
public static void main(String[] args) {
StudentHomeTest sht = new StudentHomeTest();
try {
sht.setup();
sht.testStudentHome();
sht.tearDown();
} catch (Exception ex) {
Logger.getLogger(StudentHomeTest.class.getName()).log(Level.SEVERE, null, ex);
sht.tearDown();
}
}
Now while running the test if some assertion fails the test method should (this is what I expect) throw an exception and the main method should call the tearDown method. But this does not happen. and the browser window continues to stay there.
I am using the netbeans ide for running the test.
following the junit convention
If you follow the jUnit convention, then you will know that teardown methods belong in the #After method as this method will always run after your tests.
create a new method with the #After jUnit annotation.
#After
public void tearDown() {
sht.tearDown();
}
Edit
You know what, I believe that you are running into a classic issue of assertEquals in jUnit.
Stolen from this answer...:
JUnit calls the .equals() method to determine equality in the method assertEquals(Object o1, Object o2).
So, you are definitely safe using assertEquals(string1, string2). (Because Strings are Objects)
--
Instead of using assertEquals on these calls, use assertTrue() instead.
assertTrue(sth.openNotification());
assertTrue("My Scores".equals(sth.myScores(true)));
AssertionError doesn't extend Exception - it's a Throwable.
But in any case, you should have
try {
sht.setup();
sht.testStudentHome();
} finally {
sht.tearDown();
}
No need for a catch block. main can throw Exception.