How do I unit test a method that contains a CompletableFuture?












0















I tried looking this up, but couldn't quite understand the examples I found. I have a class with a Spring AfterPropertiesSet() method that calls 2 other methods to spin off asynch calls. I'm at a loss how as to to unit test them. The method startProcessingThread() looks like this:



void startProcessingThread(executor) {
CompletableFuture.runAsync(() -> {
Path filePath = null;
do {
filePath = retrieveFromFileQueue();
submitFileForProcessing(filePath);
} while (keepRunning);
}, executor)
.handle((theVoid, exception) -> {
if (exception != null) {
LOG.error("Error submitting file for processing: " + exception);
}
return null;
});
}


I don't want to rewrite the CompletableFuture in the test method (do I?). So I figured I need to call startProcessingThread(), using Mocks (from Mockito) inside the methods that need them (retrieveFromFileQueue() and submitFileForProcessing()). But what about the CompletableFuture itself? Should I mock that? I'm sorry, but I'm really confused...










share|improve this question

























  • This code does not wait for the CompletableFutur to finish nor it uses it's result. Why did you choose it in favour to an ordinary Runnable?

    – Timothy Truckle
    Feb 10 '17 at 8:27











  • You should create the lambda in a different method (or as an class of its own). Then you can mock it and check, that this method runs it (have your test wait a few ms after calling the method), also you can verify the lambdas behavior itself directly.

    – Timothy Truckle
    Feb 10 '17 at 8:29













  • Timothy, this code is not my design. I'm not really sure why a CompletableFuture was used. Does it not have any advantages over a Runnable, the way it's currently used??

    – user1660256
    Feb 10 '17 at 12:06











  • Also, we decided we didn't want to put a sleep in a unit test method. So for now we're just going to test it during integration.

    – user1660256
    Feb 10 '17 at 12:06











  • "we decided we didn't want to put a sleep in a unit test method." wtith the change I suggestet the resulting method would be *to simple to fail" so that is would be no risk not to UnitTest is, but you could still thest the logic of the rinnable/CompletableFuture.

    – Timothy Truckle
    Feb 10 '17 at 12:11
















0















I tried looking this up, but couldn't quite understand the examples I found. I have a class with a Spring AfterPropertiesSet() method that calls 2 other methods to spin off asynch calls. I'm at a loss how as to to unit test them. The method startProcessingThread() looks like this:



void startProcessingThread(executor) {
CompletableFuture.runAsync(() -> {
Path filePath = null;
do {
filePath = retrieveFromFileQueue();
submitFileForProcessing(filePath);
} while (keepRunning);
}, executor)
.handle((theVoid, exception) -> {
if (exception != null) {
LOG.error("Error submitting file for processing: " + exception);
}
return null;
});
}


I don't want to rewrite the CompletableFuture in the test method (do I?). So I figured I need to call startProcessingThread(), using Mocks (from Mockito) inside the methods that need them (retrieveFromFileQueue() and submitFileForProcessing()). But what about the CompletableFuture itself? Should I mock that? I'm sorry, but I'm really confused...










share|improve this question

























  • This code does not wait for the CompletableFutur to finish nor it uses it's result. Why did you choose it in favour to an ordinary Runnable?

    – Timothy Truckle
    Feb 10 '17 at 8:27











  • You should create the lambda in a different method (or as an class of its own). Then you can mock it and check, that this method runs it (have your test wait a few ms after calling the method), also you can verify the lambdas behavior itself directly.

    – Timothy Truckle
    Feb 10 '17 at 8:29













  • Timothy, this code is not my design. I'm not really sure why a CompletableFuture was used. Does it not have any advantages over a Runnable, the way it's currently used??

    – user1660256
    Feb 10 '17 at 12:06











  • Also, we decided we didn't want to put a sleep in a unit test method. So for now we're just going to test it during integration.

    – user1660256
    Feb 10 '17 at 12:06











  • "we decided we didn't want to put a sleep in a unit test method." wtith the change I suggestet the resulting method would be *to simple to fail" so that is would be no risk not to UnitTest is, but you could still thest the logic of the rinnable/CompletableFuture.

    – Timothy Truckle
    Feb 10 '17 at 12:11














0












0








0








I tried looking this up, but couldn't quite understand the examples I found. I have a class with a Spring AfterPropertiesSet() method that calls 2 other methods to spin off asynch calls. I'm at a loss how as to to unit test them. The method startProcessingThread() looks like this:



void startProcessingThread(executor) {
CompletableFuture.runAsync(() -> {
Path filePath = null;
do {
filePath = retrieveFromFileQueue();
submitFileForProcessing(filePath);
} while (keepRunning);
}, executor)
.handle((theVoid, exception) -> {
if (exception != null) {
LOG.error("Error submitting file for processing: " + exception);
}
return null;
});
}


I don't want to rewrite the CompletableFuture in the test method (do I?). So I figured I need to call startProcessingThread(), using Mocks (from Mockito) inside the methods that need them (retrieveFromFileQueue() and submitFileForProcessing()). But what about the CompletableFuture itself? Should I mock that? I'm sorry, but I'm really confused...










share|improve this question
















I tried looking this up, but couldn't quite understand the examples I found. I have a class with a Spring AfterPropertiesSet() method that calls 2 other methods to spin off asynch calls. I'm at a loss how as to to unit test them. The method startProcessingThread() looks like this:



void startProcessingThread(executor) {
CompletableFuture.runAsync(() -> {
Path filePath = null;
do {
filePath = retrieveFromFileQueue();
submitFileForProcessing(filePath);
} while (keepRunning);
}, executor)
.handle((theVoid, exception) -> {
if (exception != null) {
LOG.error("Error submitting file for processing: " + exception);
}
return null;
});
}


I don't want to rewrite the CompletableFuture in the test method (do I?). So I figured I need to call startProcessingThread(), using Mocks (from Mockito) inside the methods that need them (retrieveFromFileQueue() and submitFileForProcessing()). But what about the CompletableFuture itself? Should I mock that? I'm sorry, but I'm really confused...







java unit-testing






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 8 '17 at 14:01







user1660256

















asked Feb 8 '17 at 13:54









user1660256user1660256

42741023




42741023













  • This code does not wait for the CompletableFutur to finish nor it uses it's result. Why did you choose it in favour to an ordinary Runnable?

    – Timothy Truckle
    Feb 10 '17 at 8:27











  • You should create the lambda in a different method (or as an class of its own). Then you can mock it and check, that this method runs it (have your test wait a few ms after calling the method), also you can verify the lambdas behavior itself directly.

    – Timothy Truckle
    Feb 10 '17 at 8:29













  • Timothy, this code is not my design. I'm not really sure why a CompletableFuture was used. Does it not have any advantages over a Runnable, the way it's currently used??

    – user1660256
    Feb 10 '17 at 12:06











  • Also, we decided we didn't want to put a sleep in a unit test method. So for now we're just going to test it during integration.

    – user1660256
    Feb 10 '17 at 12:06











  • "we decided we didn't want to put a sleep in a unit test method." wtith the change I suggestet the resulting method would be *to simple to fail" so that is would be no risk not to UnitTest is, but you could still thest the logic of the rinnable/CompletableFuture.

    – Timothy Truckle
    Feb 10 '17 at 12:11



















  • This code does not wait for the CompletableFutur to finish nor it uses it's result. Why did you choose it in favour to an ordinary Runnable?

    – Timothy Truckle
    Feb 10 '17 at 8:27











  • You should create the lambda in a different method (or as an class of its own). Then you can mock it and check, that this method runs it (have your test wait a few ms after calling the method), also you can verify the lambdas behavior itself directly.

    – Timothy Truckle
    Feb 10 '17 at 8:29













  • Timothy, this code is not my design. I'm not really sure why a CompletableFuture was used. Does it not have any advantages over a Runnable, the way it's currently used??

    – user1660256
    Feb 10 '17 at 12:06











  • Also, we decided we didn't want to put a sleep in a unit test method. So for now we're just going to test it during integration.

    – user1660256
    Feb 10 '17 at 12:06











  • "we decided we didn't want to put a sleep in a unit test method." wtith the change I suggestet the resulting method would be *to simple to fail" so that is would be no risk not to UnitTest is, but you could still thest the logic of the rinnable/CompletableFuture.

    – Timothy Truckle
    Feb 10 '17 at 12:11

















This code does not wait for the CompletableFutur to finish nor it uses it's result. Why did you choose it in favour to an ordinary Runnable?

– Timothy Truckle
Feb 10 '17 at 8:27





This code does not wait for the CompletableFutur to finish nor it uses it's result. Why did you choose it in favour to an ordinary Runnable?

– Timothy Truckle
Feb 10 '17 at 8:27













You should create the lambda in a different method (or as an class of its own). Then you can mock it and check, that this method runs it (have your test wait a few ms after calling the method), also you can verify the lambdas behavior itself directly.

– Timothy Truckle
Feb 10 '17 at 8:29







You should create the lambda in a different method (or as an class of its own). Then you can mock it and check, that this method runs it (have your test wait a few ms after calling the method), also you can verify the lambdas behavior itself directly.

– Timothy Truckle
Feb 10 '17 at 8:29















Timothy, this code is not my design. I'm not really sure why a CompletableFuture was used. Does it not have any advantages over a Runnable, the way it's currently used??

– user1660256
Feb 10 '17 at 12:06





Timothy, this code is not my design. I'm not really sure why a CompletableFuture was used. Does it not have any advantages over a Runnable, the way it's currently used??

– user1660256
Feb 10 '17 at 12:06













Also, we decided we didn't want to put a sleep in a unit test method. So for now we're just going to test it during integration.

– user1660256
Feb 10 '17 at 12:06





Also, we decided we didn't want to put a sleep in a unit test method. So for now we're just going to test it during integration.

– user1660256
Feb 10 '17 at 12:06













"we decided we didn't want to put a sleep in a unit test method." wtith the change I suggestet the resulting method would be *to simple to fail" so that is would be no risk not to UnitTest is, but you could still thest the logic of the rinnable/CompletableFuture.

– Timothy Truckle
Feb 10 '17 at 12:11





"we decided we didn't want to put a sleep in a unit test method." wtith the change I suggestet the resulting method would be *to simple to fail" so that is would be no risk not to UnitTest is, but you could still thest the logic of the rinnable/CompletableFuture.

– Timothy Truckle
Feb 10 '17 at 12:11












1 Answer
1






active

oldest

votes


















1














You should avoid non deterministic logic in your test and so I would advise to avoid sleep. Instead you can use Mockito's "when" instead of "verify" and wait until the action was performed:



final xyz result = new{null};
final CountDownLatch latch = new CountDownLatch(1);
when(submitFileForProcessing(...).thenAnswer((Answer<Lwm2mCommand>) invocationOnMock ->
{
result[0] = invocationOnMock.getArgument(index); // if you need to check the values passed to your method call

latch.countDown();
}

// Call your method
assertTrue(latch.await(60L, TimeUnit.SECONDS));
// If needed check the parameters passed to the mocked method


One more tip: I wouldn't mock the actual class under test - instead I would mock one of the dependencies used.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f42115038%2fhow-do-i-unit-test-a-method-that-contains-a-completablefuture%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    You should avoid non deterministic logic in your test and so I would advise to avoid sleep. Instead you can use Mockito's "when" instead of "verify" and wait until the action was performed:



    final xyz result = new{null};
    final CountDownLatch latch = new CountDownLatch(1);
    when(submitFileForProcessing(...).thenAnswer((Answer<Lwm2mCommand>) invocationOnMock ->
    {
    result[0] = invocationOnMock.getArgument(index); // if you need to check the values passed to your method call

    latch.countDown();
    }

    // Call your method
    assertTrue(latch.await(60L, TimeUnit.SECONDS));
    // If needed check the parameters passed to the mocked method


    One more tip: I wouldn't mock the actual class under test - instead I would mock one of the dependencies used.






    share|improve this answer




























      1














      You should avoid non deterministic logic in your test and so I would advise to avoid sleep. Instead you can use Mockito's "when" instead of "verify" and wait until the action was performed:



      final xyz result = new{null};
      final CountDownLatch latch = new CountDownLatch(1);
      when(submitFileForProcessing(...).thenAnswer((Answer<Lwm2mCommand>) invocationOnMock ->
      {
      result[0] = invocationOnMock.getArgument(index); // if you need to check the values passed to your method call

      latch.countDown();
      }

      // Call your method
      assertTrue(latch.await(60L, TimeUnit.SECONDS));
      // If needed check the parameters passed to the mocked method


      One more tip: I wouldn't mock the actual class under test - instead I would mock one of the dependencies used.






      share|improve this answer


























        1












        1








        1







        You should avoid non deterministic logic in your test and so I would advise to avoid sleep. Instead you can use Mockito's "when" instead of "verify" and wait until the action was performed:



        final xyz result = new{null};
        final CountDownLatch latch = new CountDownLatch(1);
        when(submitFileForProcessing(...).thenAnswer((Answer<Lwm2mCommand>) invocationOnMock ->
        {
        result[0] = invocationOnMock.getArgument(index); // if you need to check the values passed to your method call

        latch.countDown();
        }

        // Call your method
        assertTrue(latch.await(60L, TimeUnit.SECONDS));
        // If needed check the parameters passed to the mocked method


        One more tip: I wouldn't mock the actual class under test - instead I would mock one of the dependencies used.






        share|improve this answer













        You should avoid non deterministic logic in your test and so I would advise to avoid sleep. Instead you can use Mockito's "when" instead of "verify" and wait until the action was performed:



        final xyz result = new{null};
        final CountDownLatch latch = new CountDownLatch(1);
        when(submitFileForProcessing(...).thenAnswer((Answer<Lwm2mCommand>) invocationOnMock ->
        {
        result[0] = invocationOnMock.getArgument(index); // if you need to check the values passed to your method call

        latch.countDown();
        }

        // Call your method
        assertTrue(latch.await(60L, TimeUnit.SECONDS));
        // If needed check the parameters passed to the mocked method


        One more tip: I wouldn't mock the actual class under test - instead I would mock one of the dependencies used.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 31 '18 at 14:45









        Dror HelperDror Helper

        23.8k1368123




        23.8k1368123
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f42115038%2fhow-do-i-unit-test-a-method-that-contains-a-completablefuture%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Monofisismo

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas