When to use of TestContext#verify() method in vert.x - junit

I was working on a unit test for the sample vert.x app. But could not understand the purpose of TestContext#verify() method. Here are two test cases one with TestContext#verify() and another without it. Both are running fine. So when do we need to use TestContext#verify()?
Test Case without TestContext#verify():
#Test
#DisplayName("Handler Test3")
void successTestCase1(VertxTestContext testContext) {
Checkpoint checkpoint = testContext.checkpoint(1);
new SampleVerticle().doWorkWithAsyncresult("hello",
testContext.succeeding(future -> {
assertThat(future).isEqualTo("test from");
testContext.completeNow();
})
);
}
Test Case with TestContext#verify():
#Test
#DisplayName("Handler Test4")
void successTestCase2(VertxTestContext testContext) {
Checkpoint checkpoint = testContext.checkpoint(1);
new SampleVerticle().doWorkWithAsyncresult("vivek",
testContext.succeeding(future -> {
testContext.verify(() -> {
assertThat(future).isEqualTo("test from");
testContext.completeNow();
});
})
);
}
Test Method:
public void doWorkWithAsyncresult(String input, Handler<AsyncResult<String>> handler) {
handler.handle(Future.succeededFuture("test from"));
}
Thanks,
Vivek Kumar

The verify method is useful when the test fails, not when it passes.
If one of the asynchronous assertions fails, verify will report it correctly to the TestContext. Then the test will fail immediately with the right error message.
Otherwise the test would timeout after an arbitrary amount of time, and the error may or may not be printed to the console.

You code is not async. So both methods are same now. And testContext.completeNow() does nothing.
When code is async you should add to the bottom of test (VertxExtension does this for you):
assertTrue(testContext.awaitCompletion(10, TimeUnit.SECONDS), "Timeout");
assertFalse(testContext.failed());
And if assert throws exception, the test without verify will end with timeout.
To fix that you should wrap your assert and call failNow:
try {
assert...
testContext.completeNow();
} catch (Exception e) {
textContext.failNow(e);
return;
}
TextContext::verify does this wrapping for you.

Related

How to skip static validation in JUnit test with Mockito

I have a function I need to test:
#Override
public ResponseEntity<BasicResponse> myFunction(HttpServletRequest request, #RequestBody Dto dto, BindingResult result) {
try {
ValidationUtils.invokeValidator(validator, dto, result);
if (result.hasErrors()) {
// do things
} else {
//do things
}
} catch (Exception e) {
// catch
}
//return things;
}
But when I test the function it always go to the catch because of the validator, it says:
"Validator does not support Dto".
I don't care about the validation, I need to test what's inside the try, so I try to use doNothing to skip the validation but I get an error because it's void:
#Test
void TestMyFunction() {
doNothing().when(ValidationUtils.invokeValidator(validator, dto, result));
ResponseEntity<BasicResponse> response = controller.myFunction(request, dto, result);
// assert something
}
Any idea on how to proceed? I can't change the function, I can only write the test and I'm new at this. Thank you.
If ValidationUtils was an object instance that is a Mockito spy or mock, you would be able to mock it like so:
doNothing()
.when(validationUtils)
.invokeValidator(validator, dto, result);
This, unfortunately, does not seem to be the case in your test - ValidationUtils seems to be a class on which a static method is called, which Mockito can handle since version 3.4.0 (before that it was usually handled by PowerMock). thenAnswer should be used with the mockedStatic object instance, similarly to this answer, since the method's return type is void.
An important additional (but mandatory) note: mocking static methods is discouraged and should be avoided whenever possible. It slows down the tests and is a sign of bad design of the classes. The validator should be injected into the class or created using a factory, thanks to that a mocked object instance could be easily used.
I've checked that and in fact the thenAnswer part is not required to do nothing after using mockStatic on a class.
try (var mockedStatic = Mockito.mockStatic(ValidationUtils.class)) {
// test code
}
The code above makes ValidationUtils do nothing and return default values (0, false, null).
See this example (all tests pass).

Parse detect ParseClient is not initialized

I am using Parse.com in my app. I see that sometimes if Parse.ParseClient.Initialize() method fails, ParseAnalytics.TrackAppOpens still run and eventually crash my app.
So how can I detect if ParseClient failed to initialize?
In App constructor:
this.Startup += async (sender, args) =>
{
//crash if ParseClient is not initialized
//Parse.ParseAnalytics.TrackAppOpens(RootFrame);
};
One way is to make a Test Call to your Parse DB and wrap it around with try catch block before you use the ParseAnalytics.
Something like..
ParseClient.Initialize();
try
{
client.GetObject("SomeTestORDummyObject");
}
catch(Exception ex)
{
//Indicates that Initialize failed..
}
ParseAnalytics.TrackAppOpens(RootFrame);

How to implement expected exceptions?

I am trying my first features with Behat and I am facing the problem I don't know how to implement expected exceptions.
I found the issue https://github.com/Behat/Behat/issues/140 and robocoder is talking about one possible way, which is used by Behat, too. But it seems that they aren't really handling exceptions.
My point is to achieve forced exception handling. I don't want any construct catching all exceptions and forget them.
One possible way would be:
When <player> transfers <transfer> from his account it should fail with <error>
Implementation
try {
...
} catch (\Exception $ex) {
assertEquals($error, $ex->getMessage());
}
I don't like the scenario description. I want to use the then keyword, e.g.
When <player> transfers <transfer> from his account
Then it should fail with error <error>
This description has the disadvantage I need two methods:
method1($arg1, $arg2) {
// Test the transfer
}
method2($arg1, $arg2) {
// Check if the exception is the right one
}
To be able to check in method2 the exception needs to be stored.
The only possible way I see is to use a try/catch and store it to a variable.
Someone else would catch it and do nothing with it. Nobody will notice, when running the tests.
How can I prevent that exceptions are discarded?
Has anybody else a similar scenario implemented?
Thanks for any hints.
EDIT:
Behat context:
playerTransfer($player, $amount) {
$player->transfer($amount);
}
Method from entity class:
transfer($amount) {
if ($this->getWealth() < $amount) {
throw NotEnoughMoney();
}
...
}
Always try to catch method outcome to context class field, for example:
//inside Behat context class method
try {
$this->outcome = $func();
}
catch(\Exception $ex) {
$this->outcome = $ex;
}
Now when expecting exception at next step just check if $this->outcome is instanceof desired exception with message/code.
I think the problem is in your implementation. Do you check if transfer is successful in "When transfers from his account" ? Do you need to check it ?
Failure test:
When <player> transfers <transfer> from his account
Then I should see error <error>
Successful step:
When <player> transfers <transfer> from his account
Then I should see "transfer successful"
Here's how I successfully did it in a project of mine where I had to repeat a few steps till the condition held true:
/**
* #Given /^I execute some conditions$/
*/
public function executeConditions()
{
$flag = 1;
do {
try {
<steps to be executed till the condition holds true>
$flag=1;
} catch (\Exception $ex) {
$flag = 0;
}
}while ($flag>0);
}

Thucydides - Test continues after assertion in #Step fails

In the scenario below, I expect that the assertion failure in the step should make the test fail. What I am seeing is that the test continues and since a later assertion in the #Test method fails, the wrong exception is being reported, making it hard to debug.
Is there anyway I can get the test to stop when there is an assertion failure in a #Step?
#Test
public void test() {
....
steps.step1();
System.out.println("test should not reach here");
assertTrue(false);
}
#Step
public void step1() {
assertTrue(false);
}
Tried running the tests from my IDE and maven. (using ThucydidesRunner)
try to check this: http://thucydides.info/docs/thucydides/_creating_a_new_thucydides_project.html
in short words, in steps:
import net.thucydides.core.annotations.Step;
import static org.fest.assertions.Assertions.assertThat;
import static org.hamcrest.Matchers.is;
public class EndUserSteps extends Scenario Steps {
#Step
public void someStep() {
assertThat(true, is(false));
}
}
It turns out the tests don't stop, here is the reply I got from the creators of Thucydides:
"The test can't stop immediately, or it would be impossible to know what steps were not executed, so, yes, this is by design. They do record the first assertion error and then run the steps in "dry-run" mode (no WebDriver calls are made), but that's about the most it can guarantee."

Webdriver test Script Does not stop after assert failure

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.