How to test class which implements Runnable with Junit












3














I have a class implements Runnable like this



  public Processor implements Runnable{

public void run() {
while (true) {
//some code
sendRequest(object);
}
}
}

public void sendRequest(Object, object){
// do something to send the event
}
}


And in other pre-load class. I use



Processor processor = new Processor();
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(processor)


So my question is how can I unit test sendRequest method is called or not?










share|improve this question






















  • To where does sendRequest send something? It isn't clear from the example. Generally I would inject/obtain a mocked destination that can report the success/failure to the test class, with an appropriate timeout. To a certain extent, it is akin to how greenmail supports mail testing.
    – KevinO
    Nov 12 '18 at 21:12
















3














I have a class implements Runnable like this



  public Processor implements Runnable{

public void run() {
while (true) {
//some code
sendRequest(object);
}
}
}

public void sendRequest(Object, object){
// do something to send the event
}
}


And in other pre-load class. I use



Processor processor = new Processor();
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(processor)


So my question is how can I unit test sendRequest method is called or not?










share|improve this question






















  • To where does sendRequest send something? It isn't clear from the example. Generally I would inject/obtain a mocked destination that can report the success/failure to the test class, with an appropriate timeout. To a certain extent, it is akin to how greenmail supports mail testing.
    – KevinO
    Nov 12 '18 at 21:12














3












3








3







I have a class implements Runnable like this



  public Processor implements Runnable{

public void run() {
while (true) {
//some code
sendRequest(object);
}
}
}

public void sendRequest(Object, object){
// do something to send the event
}
}


And in other pre-load class. I use



Processor processor = new Processor();
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(processor)


So my question is how can I unit test sendRequest method is called or not?










share|improve this question













I have a class implements Runnable like this



  public Processor implements Runnable{

public void run() {
while (true) {
//some code
sendRequest(object);
}
}
}

public void sendRequest(Object, object){
// do something to send the event
}
}


And in other pre-load class. I use



Processor processor = new Processor();
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(processor)


So my question is how can I unit test sendRequest method is called or not?







java multithreading unit-testing junit






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 '18 at 21:05









HenlenLeeHenlenLee

737




737












  • To where does sendRequest send something? It isn't clear from the example. Generally I would inject/obtain a mocked destination that can report the success/failure to the test class, with an appropriate timeout. To a certain extent, it is akin to how greenmail supports mail testing.
    – KevinO
    Nov 12 '18 at 21:12


















  • To where does sendRequest send something? It isn't clear from the example. Generally I would inject/obtain a mocked destination that can report the success/failure to the test class, with an appropriate timeout. To a certain extent, it is akin to how greenmail supports mail testing.
    – KevinO
    Nov 12 '18 at 21:12
















To where does sendRequest send something? It isn't clear from the example. Generally I would inject/obtain a mocked destination that can report the success/failure to the test class, with an appropriate timeout. To a certain extent, it is akin to how greenmail supports mail testing.
– KevinO
Nov 12 '18 at 21:12




To where does sendRequest send something? It isn't clear from the example. Generally I would inject/obtain a mocked destination that can report the success/failure to the test class, with an appropriate timeout. To a certain extent, it is akin to how greenmail supports mail testing.
– KevinO
Nov 12 '18 at 21:12












3 Answers
3






active

oldest

votes


















3














Separate the concerns : the Runnable and the logic associated.

It will make in addition your code mode testable.

You could extract sendRequest() in a Foo class that the Processor class depends on.
Then you have just to mock this Foo class in your test and verify that the sendRequest() method was invoked.



For example :



 public Processor implements Runnable{

private Foo foo;

public Processor(Foo foo){
this.foo = foo;
}

public void run() {
while (true) {
//some code
foo.sendRequest(object);
}
}
}


And the test :



@Mock
Foo fooMock;

@Test
public void run() {
Processor processor = new Processor(fooMock);
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(processor);
executor.awaitTermination(someTime, TimeUnit.SECONDS);
Mockito.verify(fooMock).sendRequest(...);
}





share|improve this answer



















  • 1




    +1, I was thinking the same thing. It's much better to have run() just delegate out to a method so it's easier to test without the Runnable making it more complex. It won't get you 100% coverage but it's a worthwhile trade-off
    – Jimmy
    Nov 12 '18 at 21:24










  • @Jimmy Indeed complex untestable classes is really annoying. And using PowerMock or partial mocking is personally a no way. But why do you think that the coverage could be hurt by such a refactoring ?
    – davidxxx
    Nov 12 '18 at 21:33










  • @ davidxxx So I have to extract the sendRequest method to another class for unit testing?
    – HenlenLee
    Nov 12 '18 at 22:00










  • Exactly. A sane refactoring.
    – davidxxx
    Nov 13 '18 at 10:00



















2














i believe you want to test only implemented run() method, so you can call the method directly using Processor object or you can create a thread and pass runnable object to it and call Thread.start()



If sendRequest(Object object) method is doing any external operations i will suggest you to mock that method



public class ThreadTest {

@Test(//throws some exception)
public void shouldThrowSomeException() {
Processor exThread = new Processor ();
exThread.run(); //or
Thread t = new Thread(exThread);
t.start()

}
}


Mocking for mocking here



@Test(//throws some exception)
public void shouldThrowSomeException() {
Processor exThreadmock = mock(Processor.class);
when(exThreadmock.sendRequest(anyObject))
.thenThrow(SomeException.class)
Thread t = new Thread(exThread);
t.start()

}





share|improve this answer































    1














    Use Mockito.spy for partial mocking.



    Processor processor = spy(new Processor());

    doCallRealMethod().when(processor).run();

    verify(processor).sendRequest(mock1, mock2);





    share|improve this answer























    • I follow your steps but the sendRequest method is not invoked
      – HenlenLee
      Nov 12 '18 at 21:30











    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%2f53270084%2fhow-to-test-class-which-implements-runnable-with-junit%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    Separate the concerns : the Runnable and the logic associated.

    It will make in addition your code mode testable.

    You could extract sendRequest() in a Foo class that the Processor class depends on.
    Then you have just to mock this Foo class in your test and verify that the sendRequest() method was invoked.



    For example :



     public Processor implements Runnable{

    private Foo foo;

    public Processor(Foo foo){
    this.foo = foo;
    }

    public void run() {
    while (true) {
    //some code
    foo.sendRequest(object);
    }
    }
    }


    And the test :



    @Mock
    Foo fooMock;

    @Test
    public void run() {
    Processor processor = new Processor(fooMock);
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.execute(processor);
    executor.awaitTermination(someTime, TimeUnit.SECONDS);
    Mockito.verify(fooMock).sendRequest(...);
    }





    share|improve this answer



















    • 1




      +1, I was thinking the same thing. It's much better to have run() just delegate out to a method so it's easier to test without the Runnable making it more complex. It won't get you 100% coverage but it's a worthwhile trade-off
      – Jimmy
      Nov 12 '18 at 21:24










    • @Jimmy Indeed complex untestable classes is really annoying. And using PowerMock or partial mocking is personally a no way. But why do you think that the coverage could be hurt by such a refactoring ?
      – davidxxx
      Nov 12 '18 at 21:33










    • @ davidxxx So I have to extract the sendRequest method to another class for unit testing?
      – HenlenLee
      Nov 12 '18 at 22:00










    • Exactly. A sane refactoring.
      – davidxxx
      Nov 13 '18 at 10:00
















    3














    Separate the concerns : the Runnable and the logic associated.

    It will make in addition your code mode testable.

    You could extract sendRequest() in a Foo class that the Processor class depends on.
    Then you have just to mock this Foo class in your test and verify that the sendRequest() method was invoked.



    For example :



     public Processor implements Runnable{

    private Foo foo;

    public Processor(Foo foo){
    this.foo = foo;
    }

    public void run() {
    while (true) {
    //some code
    foo.sendRequest(object);
    }
    }
    }


    And the test :



    @Mock
    Foo fooMock;

    @Test
    public void run() {
    Processor processor = new Processor(fooMock);
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.execute(processor);
    executor.awaitTermination(someTime, TimeUnit.SECONDS);
    Mockito.verify(fooMock).sendRequest(...);
    }





    share|improve this answer



















    • 1




      +1, I was thinking the same thing. It's much better to have run() just delegate out to a method so it's easier to test without the Runnable making it more complex. It won't get you 100% coverage but it's a worthwhile trade-off
      – Jimmy
      Nov 12 '18 at 21:24










    • @Jimmy Indeed complex untestable classes is really annoying. And using PowerMock or partial mocking is personally a no way. But why do you think that the coverage could be hurt by such a refactoring ?
      – davidxxx
      Nov 12 '18 at 21:33










    • @ davidxxx So I have to extract the sendRequest method to another class for unit testing?
      – HenlenLee
      Nov 12 '18 at 22:00










    • Exactly. A sane refactoring.
      – davidxxx
      Nov 13 '18 at 10:00














    3












    3








    3






    Separate the concerns : the Runnable and the logic associated.

    It will make in addition your code mode testable.

    You could extract sendRequest() in a Foo class that the Processor class depends on.
    Then you have just to mock this Foo class in your test and verify that the sendRequest() method was invoked.



    For example :



     public Processor implements Runnable{

    private Foo foo;

    public Processor(Foo foo){
    this.foo = foo;
    }

    public void run() {
    while (true) {
    //some code
    foo.sendRequest(object);
    }
    }
    }


    And the test :



    @Mock
    Foo fooMock;

    @Test
    public void run() {
    Processor processor = new Processor(fooMock);
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.execute(processor);
    executor.awaitTermination(someTime, TimeUnit.SECONDS);
    Mockito.verify(fooMock).sendRequest(...);
    }





    share|improve this answer














    Separate the concerns : the Runnable and the logic associated.

    It will make in addition your code mode testable.

    You could extract sendRequest() in a Foo class that the Processor class depends on.
    Then you have just to mock this Foo class in your test and verify that the sendRequest() method was invoked.



    For example :



     public Processor implements Runnable{

    private Foo foo;

    public Processor(Foo foo){
    this.foo = foo;
    }

    public void run() {
    while (true) {
    //some code
    foo.sendRequest(object);
    }
    }
    }


    And the test :



    @Mock
    Foo fooMock;

    @Test
    public void run() {
    Processor processor = new Processor(fooMock);
    ExecutorService executor = Executors.newCachedThreadPool();
    executor.execute(processor);
    executor.awaitTermination(someTime, TimeUnit.SECONDS);
    Mockito.verify(fooMock).sendRequest(...);
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 14 '18 at 19:57

























    answered Nov 12 '18 at 21:22









    davidxxxdavidxxx

    64.3k56193




    64.3k56193








    • 1




      +1, I was thinking the same thing. It's much better to have run() just delegate out to a method so it's easier to test without the Runnable making it more complex. It won't get you 100% coverage but it's a worthwhile trade-off
      – Jimmy
      Nov 12 '18 at 21:24










    • @Jimmy Indeed complex untestable classes is really annoying. And using PowerMock or partial mocking is personally a no way. But why do you think that the coverage could be hurt by such a refactoring ?
      – davidxxx
      Nov 12 '18 at 21:33










    • @ davidxxx So I have to extract the sendRequest method to another class for unit testing?
      – HenlenLee
      Nov 12 '18 at 22:00










    • Exactly. A sane refactoring.
      – davidxxx
      Nov 13 '18 at 10:00














    • 1




      +1, I was thinking the same thing. It's much better to have run() just delegate out to a method so it's easier to test without the Runnable making it more complex. It won't get you 100% coverage but it's a worthwhile trade-off
      – Jimmy
      Nov 12 '18 at 21:24










    • @Jimmy Indeed complex untestable classes is really annoying. And using PowerMock or partial mocking is personally a no way. But why do you think that the coverage could be hurt by such a refactoring ?
      – davidxxx
      Nov 12 '18 at 21:33










    • @ davidxxx So I have to extract the sendRequest method to another class for unit testing?
      – HenlenLee
      Nov 12 '18 at 22:00










    • Exactly. A sane refactoring.
      – davidxxx
      Nov 13 '18 at 10:00








    1




    1




    +1, I was thinking the same thing. It's much better to have run() just delegate out to a method so it's easier to test without the Runnable making it more complex. It won't get you 100% coverage but it's a worthwhile trade-off
    – Jimmy
    Nov 12 '18 at 21:24




    +1, I was thinking the same thing. It's much better to have run() just delegate out to a method so it's easier to test without the Runnable making it more complex. It won't get you 100% coverage but it's a worthwhile trade-off
    – Jimmy
    Nov 12 '18 at 21:24












    @Jimmy Indeed complex untestable classes is really annoying. And using PowerMock or partial mocking is personally a no way. But why do you think that the coverage could be hurt by such a refactoring ?
    – davidxxx
    Nov 12 '18 at 21:33




    @Jimmy Indeed complex untestable classes is really annoying. And using PowerMock or partial mocking is personally a no way. But why do you think that the coverage could be hurt by such a refactoring ?
    – davidxxx
    Nov 12 '18 at 21:33












    @ davidxxx So I have to extract the sendRequest method to another class for unit testing?
    – HenlenLee
    Nov 12 '18 at 22:00




    @ davidxxx So I have to extract the sendRequest method to another class for unit testing?
    – HenlenLee
    Nov 12 '18 at 22:00












    Exactly. A sane refactoring.
    – davidxxx
    Nov 13 '18 at 10:00




    Exactly. A sane refactoring.
    – davidxxx
    Nov 13 '18 at 10:00













    2














    i believe you want to test only implemented run() method, so you can call the method directly using Processor object or you can create a thread and pass runnable object to it and call Thread.start()



    If sendRequest(Object object) method is doing any external operations i will suggest you to mock that method



    public class ThreadTest {

    @Test(//throws some exception)
    public void shouldThrowSomeException() {
    Processor exThread = new Processor ();
    exThread.run(); //or
    Thread t = new Thread(exThread);
    t.start()

    }
    }


    Mocking for mocking here



    @Test(//throws some exception)
    public void shouldThrowSomeException() {
    Processor exThreadmock = mock(Processor.class);
    when(exThreadmock.sendRequest(anyObject))
    .thenThrow(SomeException.class)
    Thread t = new Thread(exThread);
    t.start()

    }





    share|improve this answer




























      2














      i believe you want to test only implemented run() method, so you can call the method directly using Processor object or you can create a thread and pass runnable object to it and call Thread.start()



      If sendRequest(Object object) method is doing any external operations i will suggest you to mock that method



      public class ThreadTest {

      @Test(//throws some exception)
      public void shouldThrowSomeException() {
      Processor exThread = new Processor ();
      exThread.run(); //or
      Thread t = new Thread(exThread);
      t.start()

      }
      }


      Mocking for mocking here



      @Test(//throws some exception)
      public void shouldThrowSomeException() {
      Processor exThreadmock = mock(Processor.class);
      when(exThreadmock.sendRequest(anyObject))
      .thenThrow(SomeException.class)
      Thread t = new Thread(exThread);
      t.start()

      }





      share|improve this answer


























        2












        2








        2






        i believe you want to test only implemented run() method, so you can call the method directly using Processor object or you can create a thread and pass runnable object to it and call Thread.start()



        If sendRequest(Object object) method is doing any external operations i will suggest you to mock that method



        public class ThreadTest {

        @Test(//throws some exception)
        public void shouldThrowSomeException() {
        Processor exThread = new Processor ();
        exThread.run(); //or
        Thread t = new Thread(exThread);
        t.start()

        }
        }


        Mocking for mocking here



        @Test(//throws some exception)
        public void shouldThrowSomeException() {
        Processor exThreadmock = mock(Processor.class);
        when(exThreadmock.sendRequest(anyObject))
        .thenThrow(SomeException.class)
        Thread t = new Thread(exThread);
        t.start()

        }





        share|improve this answer














        i believe you want to test only implemented run() method, so you can call the method directly using Processor object or you can create a thread and pass runnable object to it and call Thread.start()



        If sendRequest(Object object) method is doing any external operations i will suggest you to mock that method



        public class ThreadTest {

        @Test(//throws some exception)
        public void shouldThrowSomeException() {
        Processor exThread = new Processor ();
        exThread.run(); //or
        Thread t = new Thread(exThread);
        t.start()

        }
        }


        Mocking for mocking here



        @Test(//throws some exception)
        public void shouldThrowSomeException() {
        Processor exThreadmock = mock(Processor.class);
        when(exThreadmock.sendRequest(anyObject))
        .thenThrow(SomeException.class)
        Thread t = new Thread(exThread);
        t.start()

        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 12 '18 at 22:38

























        answered Nov 12 '18 at 21:14









        DeadpoolDeadpool

        4,4692326




        4,4692326























            1














            Use Mockito.spy for partial mocking.



            Processor processor = spy(new Processor());

            doCallRealMethod().when(processor).run();

            verify(processor).sendRequest(mock1, mock2);





            share|improve this answer























            • I follow your steps but the sendRequest method is not invoked
              – HenlenLee
              Nov 12 '18 at 21:30
















            1














            Use Mockito.spy for partial mocking.



            Processor processor = spy(new Processor());

            doCallRealMethod().when(processor).run();

            verify(processor).sendRequest(mock1, mock2);





            share|improve this answer























            • I follow your steps but the sendRequest method is not invoked
              – HenlenLee
              Nov 12 '18 at 21:30














            1












            1








            1






            Use Mockito.spy for partial mocking.



            Processor processor = spy(new Processor());

            doCallRealMethod().when(processor).run();

            verify(processor).sendRequest(mock1, mock2);





            share|improve this answer














            Use Mockito.spy for partial mocking.



            Processor processor = spy(new Processor());

            doCallRealMethod().when(processor).run();

            verify(processor).sendRequest(mock1, mock2);






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 12 '18 at 21:20









            ETO

            1,986422




            1,986422










            answered Nov 12 '18 at 21:14









            Hans van KesselsHans van Kessels

            8812




            8812












            • I follow your steps but the sendRequest method is not invoked
              – HenlenLee
              Nov 12 '18 at 21:30


















            • I follow your steps but the sendRequest method is not invoked
              – HenlenLee
              Nov 12 '18 at 21:30
















            I follow your steps but the sendRequest method is not invoked
            – HenlenLee
            Nov 12 '18 at 21:30




            I follow your steps but the sendRequest method is not invoked
            – HenlenLee
            Nov 12 '18 at 21:30


















            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53270084%2fhow-to-test-class-which-implements-runnable-with-junit%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

            The Sandy Post

            Danny Elfman

            Pages that link to "Head v. Amoskeag Manufacturing Co."