How to prevent a method from calling another method in test? - java

public void makeLoginRequest(){
view.log(sessionHandler.getEncodedCredentials());
Call loginCall = apiService.getLoginInfo("application/json", "application/json"
, "SPT", "Android", sessionHandler.getEncodedCredentials());
loginCall.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
handleLoginResponse(response);
}
#Override
public void onFailure(Call<User> call, Throwable t) {
handleLoginFailure(t);
}
});
}
I'm trying to test this method with JUnit and Mockito. This method belongs in a presenter class. In order to test this I run
presenter.makeLoginRequest(); then when the onResponse is called
I use verify(presenter).handleLoginResponse(response); which never gets called. The issue is that it will continue to run everything in handleLoginResponse(response);. I don't want to execute whats in this method, but only need to verify that this method gets called.
How can I ignore the method execution, or what is the best way to test this?

There 2 ways of doing this:
Make your presenter become a mock object
presenter = mock<Presenter>()
Add this to your test
doNothing().when(presenter).handleLoginResponse(any());

Related

call a method only on successful execution of run method of thread class in java. like in predestroy logic or something

Inside springboot when the thread gets executed successfully then only the required method should gets executed. Otherwise in case if thread gets killed abnormally dont want to execute any method just leave like that only.
I have to handle the successful thread execution scenario only with this.
for eg.
#Component
#Scope("prototype")
public class TestWatcher extends Thread
{
#Override
public void run()
{
//do something
}
//like destroy or something
public void afterThreadSuccessOnly()
{
//executes only on successful execution of run method.
}
}
I have tried this with springboot #PreDestroy annotation but it does not work if the component is prototype.
is there any solution to achieve this scenario, please anyone help me with that.
Assuming you mean to define 'success' as: Did not throw an exception and ran its natural course or executed a return statement, then, what's wrong with the rather obvious:
#Override
public void run() {
doJob();
afterThreadSuccessOnly();
}
public void doJob() {
// do something
}
public void afterThreadSuccessOnly() {
}

How to assign return value of inner class to outer variable

I am beginner in Java and i am stuck with assigning return value of a variable from an anonymous inner class.
I wanted to capture List of strings which are returned from a API Call.
List<String> **strTopics**=null;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
Call<List<String>> call=retrofit.getSubjects();
call.enqueue(new Callback<List<String>>() {
#Override
public void onResponse(Call<List<String>> call, Response<List<String>> response) {
Log.d("prepareListData","I am success");
strTopics=response.body();
for(String str:strTopics)
Log.d("Subject Name ",str)
}
#Override
public void onFailure(Call<List<String>> call, Throwable t) {
Log.d("prepareListData","I am failure");
}
});
//I am having challenges here. After this statement, again "**strTopics**" is becoming null.
for(String str:strTopics)
Log.d("After inner method",str)
I just wanted to mention, if i comment the above for loop, then only i am able to print the subject names which are inside the inner class method.
If it is uncomment, then none of the for loops are invoked and nothing is getting printed. Getting NullPointerException in 2nd for loop. Not sure it is problem of Retrofit2 also.
Can someone help me how to overcome this problem. Whatever returned from inner class, i want those values to be used outside of it.
Please help.
If you want to display the results outside the call, you will have to wait that the call has been done. In retrofit, call.enqueue is an asynchronous task, which means that it is executed on a different thread, and it might take some time to get the result.
Here, your second loop, outside the enqueue, is actually executed before the call is finished. That's why it's still null when you are trying to access it.
To resume, it is actually executed in this order:
first you create your call with Call<List<String>> call=retrofit.getSubjects();
then you add a callback to it. This launches a background task that will get the desired informations
while the background task executes, the main thread will move to the next instruction, which is your second for loop
at some point, the background task finishes, and will call either the onResponse or onFailure method that you declared in the callback
then the code inside the corresponding method is executed
It might be possible on some occasion that the background task finishes before the next instruction is started on the main thread, but you can never be sure so I wouldn't count on it.
If you need to use the result from your call somewhere else in your code, I suggest you create a method that takes the result as parameter, and call this method in the onResponse of your code.
void doSomethingWithResult(List<String> result) {
// do whatever you need with that result
}
// then in your call
call.enqueue(new Callback<List<String>>() {
#Override
public void onResponse(Call<List<String>> call, Response<List<String>> response) {
Log.d("prepareListData","I am success");
strTopics=response.body();
for(String str:strTopics)
Log.d("Subject Name ",str)
doSomethingWithResult(response.body());
}
#Override
public void onFailure(Call<List<String>> call, Throwable t) {
Log.d("prepareListData","I am failure");
}
});

Mockito: mock async method [duplicate]

This question already has answers here:
Calling callbacks with Mockito
(4 answers)
Closed 9 years ago.
I need to test this method with JUnit and Mockito
function uploadData() {
myObject.getThreadPool().execute(new Runnable() {
#Override
public void run() {
upload(arguments, callbackContext);
}
});
}
How to mock myObject to call upload(arguments, callbackContext) not in background thread ?
You'll need to do a few things here. First, replace the ThreadPool with a mock, so you have access to mock execute at all. Then use an ArgumentCaptor in a verify call to get access to the Runnable. Finally, trigger the Runnable and test the state afterwards.
#Test public void shouldUploadInBackground() {
// declare local variables
MyObject mockMyObject = Mockito.mock(MyObject.class);
ThreadPool mockThreadPool = Mockito.mock(ThreadPool.class);
ArgumentCaptor<Runnable> runnableCaptor =
ArgumentCaptor.forClass(Runnable.class);
// create the system under test
when(mockMyObject.getThreadPool()).thenReturn(mockThreadPool);
SystemUnderTest yourSystemUnderTest = createSystem(mockThreadPool);
// run the method under test
yourSystemUnderTest.uploadData();
// set the runnableCaptor to hold your callback
verify(mockThreadPool).execute(runnableCaptor.capture());
// here you can test state BEFORE the callback executes
assertFalse(yourSystemUnderTest.isDataUploaded());
// call run on the callback
runnableCaptor.getValue().run();
// here you can test state AFTER the callback executes
assertTrue(yourSystemUnderTest.isDataUploaded());
}
I think the following would work:
Mockito.doAnswer(new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
upload(arguments, callbackContext);
}).when(myObjectSpy.getThreadPool()).execute(Mockito.any(Runnable.class));
but i am not realy sure.

Calling callbacks with Mockito

I have some code
service.doAction(request, Callback<Response> callback);
How can I using Mockito grab the callback object, and call callback.reply(x)
You want to set up an Answer object that does that. Have a look at the Mockito documentation, at
https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#answer_stubs
You might write something like
when(mockService.doAction(any(Request.class), any(Callback.class))).thenAnswer(
new Answer<Object>() {
Object answer(InvocationOnMock invocation) {
((Callback<Response>) invocation.getArguments()[1]).reply(x);
return null;
}
});
(replacing x with whatever it ought to be, of course)
Consider using an ArgumentCaptor, which in any case is a closer match to "grab[bing] the callback object".
/**
* Captor for Response callbacks. Populated by MockitoAnnotations.initMocks().
* You can also use ArgumentCaptor.forClass(Callback.class) but you'd have to
* cast it due to the type parameter.
*/
#Captor ArgumentCaptor<Callback<Response>> callbackCaptor;
#Test public void testDoAction() {
// Cause service.doAction to be called
// Now call callback. ArgumentCaptor.capture() works like a matcher.
verify(service).doAction(eq(request), callbackCaptor.capture());
assertTrue(/* some assertion about the state before the callback is called */);
// Once you're satisfied, trigger the reply on callbackCaptor.getValue().
callbackCaptor.getValue().reply(x);
assertTrue(/* some assertion about the state after the callback is called */);
}
While an Answer is a good idea when the callback needs to return immediately (read: synchronously), it also introduces the overhead of creating an anonymous inner class, and unsafely casting the elements from invocation.getArguments()[n] to the data type you want. It also requires you to make any assertions about the pre-callback state of the system from WITHIN the Answer, which means that your Answer may grow in size and scope.
Instead, treat your callback asynchronously: Capture the Callback object passed to your service using an ArgumentCaptor. Now you can make all of your assertions at the test method level and call reply when you choose. This is of particular use if your service is responsible for multiple simultaneous callbacks, because you have more control over the order in which the callbacks return.
If you have a method like:
public void registerListener(final IListener listener) {
container.registerListener(new IListener() {
#Override
public void beforeCompletion() {
}
#Override
public void afterCompletion(boolean succeeded) {
listener.afterCompletion(succeeded);
}
});
}
Then following way you can mock the above method easily:
#Mock private IListener listener;
#Test
public void test_registerListener() {
target.registerListener(listener);
ArgumentCaptor<IListener> listenerCaptor =
ArgumentCaptor.forClass(IListener.class);
verify(container).registerListener(listenerCaptor.capture());
listenerCaptor.getValue().afterCompletion(true);
verify(listener).afterCompletion(true);
}
I hope this might help someone, as I had spend lot of time in figuring out this solution.
when(service.doAction(any(Request.class), any(Callback.class))).thenAnswer(
new Answer() {
Object answer(InvocationOnMock invocation) {
Callback<Response> callback =
(Callback<Response>) invocation.getArguments()[1];
callback.reply(/*response*/);
}
});

JUnit/Mockito test failing for bizarre reason

I have a very simple method that I am trying to unit test:
public class MyAntTask extends org.apache.tools.ant.Task {
public void execute() {
fire();
}
public void fire() {
// Do stuff
}
}
I just want to write a unit test that confirms that calling execute() always invokes fire(), so I wrote this:
#Test
public void executeCallsFire() {
//GIVEN
MyAntTask myTask = Mockito.mock(MyAntTask.class);
// Configure the mock to throw an exception if the fire() method
// is called.
Mockito.doThrow(new RuntimeException("fired")).when(myTask).fire();
// WHEN
try {
// Execute the execute() method.
myTask.execute();
// We should never get here; HOWEVER this is the fail() that's
// being executed by JUnit and causing the test to fail.
Assert.fail();
}
catch(Exception exc) {
// THEN
// The fire() method should have been called.
if(!exc.getMessage().equals("fired"))
Assert.fail();
}
}
I guess (and I'm by no means an expert) Mockito normally can't mock methods that return void, but this is a workaround. You basically say "wrap my object with a Mock that will always return a specific RuntimeException whenever a particular method is about to get executed". So, instead of fire() actually executing, Mockito just sees that its about to execute and throws an exception instead. Execution verified? Check.
Instead of passing, it fails at the first Assert.fail() just below the call to myTask.execute().
For the life of me, I can't figure out why. Here's the first 10-or-so lines of the enormous stack trace JUnit is giving me for the fail:
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.fail(Assert.java:100)
at net.myproj.ant.tasks.MyAntTaskUnitTest.executeCallsFire(MyAntTaskUnitTest.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
Any thoughts here, ye Mockito Gurus of StackOverflow? Thanks in advance!
Because myTask is a mock, the real object isn't called at all. To call a real object, use a spy.
You can test that a method is called using verify so there's no need for the exceptions.
public void executeCallsFire() {
MyAntTask myTask = Mockito.spy(new MyAntTask());
myTask.execute();
Mockito.verify(myTask).fire();
}
Wanting to mock the object that you're testing doesn't seem right though. It's usually better to design the test so that you're verifying calls to a separate object instead.
I see here more design issue:
why do you need one line method and both of them are public?
the mocks are for simulating dependencies and not for the class under test
if you'll make fire (quite unclear name) as private. You shouldn't test private behavior of your class

Categories