How to test class which implements Runnable with Junit
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
add a comment |
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
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
add a comment |
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
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
java multithreading unit-testing junit
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
add a comment |
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
add a comment |
3 Answers
3
active
oldest
votes
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(...);
}
1
+1, I was thinking the same thing. It's much better to haverun()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
add a comment |
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()
}
add a comment |
Use Mockito.spy for partial mocking.
Processor processor = spy(new Processor());
doCallRealMethod().when(processor).run();
verify(processor).sendRequest(mock1, mock2);
I follow your steps but the sendRequest method is not invoked
– HenlenLee
Nov 12 '18 at 21:30
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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(...);
}
1
+1, I was thinking the same thing. It's much better to haverun()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
add a comment |
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(...);
}
1
+1, I was thinking the same thing. It's much better to haverun()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
add a comment |
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(...);
}
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(...);
}
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 haverun()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
add a comment |
1
+1, I was thinking the same thing. It's much better to haverun()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
add a comment |
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()
}
add a comment |
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()
}
add a comment |
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()
}
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()
}
edited Nov 12 '18 at 22:38
answered Nov 12 '18 at 21:14
DeadpoolDeadpool
4,4692326
4,4692326
add a comment |
add a comment |
Use Mockito.spy for partial mocking.
Processor processor = spy(new Processor());
doCallRealMethod().when(processor).run();
verify(processor).sendRequest(mock1, mock2);
I follow your steps but the sendRequest method is not invoked
– HenlenLee
Nov 12 '18 at 21:30
add a comment |
Use Mockito.spy for partial mocking.
Processor processor = spy(new Processor());
doCallRealMethod().when(processor).run();
verify(processor).sendRequest(mock1, mock2);
I follow your steps but the sendRequest method is not invoked
– HenlenLee
Nov 12 '18 at 21:30
add a comment |
Use Mockito.spy for partial mocking.
Processor processor = spy(new Processor());
doCallRealMethod().when(processor).run();
verify(processor).sendRequest(mock1, mock2);
Use Mockito.spy for partial mocking.
Processor processor = spy(new Processor());
doCallRealMethod().when(processor).run();
verify(processor).sendRequest(mock1, mock2);
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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