Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java unit testing: the easiest way to test if a callback is invoked

I often work with methods that accept callbacks, and callbacks seem to be somewhat hard to test. Let's consider the following scenario, if there's a method that accepts a callback with a single method (for simplicity, I assume the testing method is synchronous), the following boilerplate could be written just to ensure that a callback method is invoked:

@Test
public void testMethod() {
    final boolean[] passed = {false};
    method(new Callback() {
        @Override
        public void handle(boolean isSuccessful) {
            passed[0] = isSuccessful;
        }
    });
    assertTrue(passed[0]);
}

It looks like a surrogate. I would like to know: is there a more elegant way to test such code to make the code above look more like the pseudo-code below?

@Test
public void testMethod() {
    // nothing explicit here, implicit boolean state provided by a test-runner
    method(new Callback() {
        @Override
        public void handle(boolean isSuccessful) {
            if ( isSuccessful ) {
                pass(); // not sure how it should look like:
                        // * an inherited method that sets the state to "true"
                        // * or an object with the pass method
                        // * whatever
                        // but doesn't exit testMethod(), just sets the state
            }
        }
    });
    // nothing explicit here too:
    // test runner might check if the state is changed to true
    // otherwise an AssertionError might be thrown at the end of the method implicitly
}

A little cleaner. Is it possible in JUnit, TestNG or any other testing framework? Thanks!


UPDATE

Sorry, I seem to have asked a vague question that doesn't really meets what I wanted to ask. I basically meant any code (not necessarily a callback) that might be invoked if certain conditions are satisfied just to set the result state to true. Simply speaking, I just want to get rid of the initial boolean[] passed and the final assertTrue(passed[0]) assuming that they are some kind of prologue and epilogue respectively and assuming that the initial state is set to false so the pass() should be invoked to set the state to true. No matter how the passed[0] is set to true, no matter where from. But unfortunately I have asked this question using the context of callbacks, however this is just an option, not a requirement. Thus the title of the question does not reflect what I really wanted to ask, but before the update some answers have been posted.

like image 672
Lyubomyr Shaydariv Avatar asked Dec 07 '14 22:12

Lyubomyr Shaydariv


People also ask

Is spring boot test a unit test?

React Full Stack Web Development With Spring BootUnit Testing is a one of the testing done by the developers to make sure individual unit or component functionalities are working fine. In this tutorial, we are going to see how to write a unit test case by using Mockito and Web Controller.

Does Java do unit testing?

Unit Testing is a methodology of testing source code for its fitment of use in production. We start out writing unit tests by creating various test cases to verify the behaviors of an individual unit of source code.


1 Answers

This is typically what a mocking framework can do for you.

With Mockito for instance:

// imports ommited for brevity
@Test
public void callbackIsCalled()
{
    final CallBack callBack = mock(CallBack.class);
    method(callBack);

    verify(callBack, only()).handle(any());
}

Of course, this is an example of verification mode (only()) and value matcher (any()). You can do more...

(other mocking frameworks exist, but I personally find Mockito the easiest to use, in addition to being one of the most powerful)

like image 149
fge Avatar answered Oct 31 '22 00:10

fge