2

I have a class that I want to test using mockito. The best way to describe the class is to paste the code, but I will try and do my best in a short phrase.

The class has one void function and calls another object that is passed in via setter and getter methods. The object that is being called (from the void function) is an asynchronous call.

The problem I am facing is mocking the asynchronous call that void function (testing via junit) uses.

public class Tester {

    private Auth auth; // not mock'ed or spy'ed
    @Mock private Http transport;

    @Before
    ....

    @Test
    public void testVoidFunctionFromAuth() {

        doAnswer(new Answer<Object>() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                return doOutput();
            }
        }).when(transport).executeAsync(param1, param2, param3...);

        auth.obtainAuth(); // void function that uses transport mock class
        // obtainAuth calls transport.executeAsync()
        // as part of the code

    }

    // return type of transport.executeAsync() is
    // ListenableFuture<ResponseEntity<String>>
    private ListenableFuture<ResponseEntity<String>> doOutput() {       
        return new SimpleAsyncTaskExecutor()
            .submitListenable(new Callable<ResponseEntity<String>>() { 
            @Override
            public ResponseEntity<String> call() throws Exception {
                ....
                return responseEntity
            }
        });
    }
}

What happens is that the doOutput() function gets called before the auth.obtainAuth(); and when obtainAuth() tries to call doOutput() it returns null -- most likely because doOutput was already execute on the line before. I am not sure how to bind/inject the mock'ed class (transport) on the call executeAsync.

Patrick
  • 1,615
  • 6
  • 18
  • 27
Adam
  • 490
  • 5
  • 17

1 Answers1

0

I'm not sure if I understood the question, but as chrylis pointed, the mock object returns a value instantly.

Unit test should have their own context, and not depend on external resources, so there is no point on testing the async call itself. It should return different values so you are able to test the behaviour of the classes that uses it.

To have a better understanding of mock definition take a look at this post: What is Mocking?

Quoting from Pro Spring MVC with Web Flow, a unit test should

Run fast: A unit test must run extremely fast. If it needs to wait for database connections or external server processes, or to parse large files, its usefulness will quickly become limited. A test should provide an immediate response and instant gratification.

Have zero external configuration: A unit test must not require any external configuration files, not even simple text files. The test’s configurations must be provided and set by the test framework itself by calling code. The intent is to minimize both the runtime of the test and to eliminate external dependencies (which can change over time, becoming out of sync with the test). Test case conditions should be expressed in the test framework, creating more readable test conditions.

Run independent of other tests: A unit test must be able to run in complete isolation. In other words, the unit test can’t depend on some other test running before or after itself. Each test is a stand-alone unit. In fact, every test method inside a test should be stand-alone and not depend on another method or on the test methods being run in a certain order. • Depend on zero external resources: A unit test must not depend on any outside resources, such as database connections or web services. Not only will these resources slow the test down, but they are outside the control of the test and thus aren’t guaranteed to be in a correct state for testing.

Leave external state untouched: A unit test must not leave any evidence that it ever ran. Unit tests are written to be repeatable, so they must clean up after themselves. Obviously, this is much easier when the test doesn’t rely on external resources (which are often harder to clean up or restore).

Test smallest unit of code possible: A unit test must test the smallest unit of code possible in order to isolate the code under test. In object-oriented programming, this unit is usually a method of an object or class. Writing unit tests such that a method is tested independently of other methods reduces the number of code lines that could contain a potential bug.

Community
  • 1
  • 1
Luke SpringWalker
  • 1,550
  • 2
  • 14
  • 32