I am trying to mock a call to instance of another class from my class. The issue I am seeing is that it looks like my mock object is not being replaced with the real object when I run my test. I made a simple example here to explain the case. Here I want to print tada instead of this is awsome which the method printAwsome() does by default. I have put my code in link below for reference please let me know what am I doing wrong if anything.
https://gist.github.com/anonymous/1eab366c60efb75b9075f100a67c851b
ExcelSupporTest prints this is awsome instead of tada when I try to mock optionPane.printAwsome() can someone point me to what am I doing wrong here.
To what I can infer form the question, if you are trying to mock a call to the method showMessageDialog, try mocking DefaultOptionPane as follows:
DefaultOptionPane defaultOptionPane = mock(DefaultOptionPane.class);
when(defaultOptionPane.showMessageDialog(anyObject(), anyObject(), anyString(), anyInt()))
.then(//do what you want to do here <Answer>);
What this simply means as its readable as well is whenever you make a call to showMessageDialog with any set of params you want to return something that you state as an Answer in then.
So long story short unless you pass it in as a parameter to method you cannot mock the method call.
It becomes an issue with scoping so replace this
public void testMethod() {
DefaultOptionPane optionPane = new DefaultOptionPane();
System.out.println("Entering method");
optionPane.printAwsome();
System.out.println("Exiting Method");
}
with this
public void testMethod(DefaultOptionPane optionPane) {
System.out.println("Entering method");
System.out.println(optionPane.printAwsome());
System.out.println("Exiting Method");
}
and then you can mock the optionPane
Related
I need to test the Exception but it gets the following error.
org.testng.TestException:
Method ContactIdentifierHelperTest.test()
[pri:0, instance:se.cambio.contactadministration.contact.helper.ContactIdentifierHelperTest#6d7b4f4c]
should have thrown an exception of type class SpiderException
Test method:
#Test(expectedExceptions = { SpiderException.class })
public void test() {
ContactData contactData = getContactData();
contactIdentifierHelper.getSpellId(contactData);
}
Method tested:
public String getSpellId(final ContactData contactData)
{
String s = null;
try
{
s = someMethod();
}
catch (SpiderException e)
{
e.printStackTrace();
}
return s;
}
Where have I gone wrong in this?
The expected behavior is that your method throws an Exception and your test fails, but it cannot never be successful (and this is correct), because you catch the exception in the body of your method.
In order to throw the exception you can simply have:
public String getSpellId(final ContactData contactData) throws SpiderException
{
return someMethod();
}
However, keep in mind that your test will be successful only if someMethod() effectively throws an exception!
Now, let me make a remark: this test does not have any sense: you are testing getSpellId but your buisiness logic is inside someMethod, and furthemore, getSpellId accept a parameter that is never used in the body ...
I suggest you change the way you think about this.
You need a repeatable, predictable way for your tested method to thrown an exception. One way to achieve that is via certain inputs.
Imagine your method looks something like this:
public String getSpellId(final ContactData contactData) throws SpiderException
{
if ( contactData == null ) throw new ArgumentException("input is null")
//some other code
}
this is something repeatable, you can always trigger the exception by passing null. You know how your code should behave, there is no uncertainty and you can test for this behaviour.
What you have however is another method call, which might fail, but you don't know how and why. This is a big no, when it comes to unit testing.
You might be better served by adding an exception test for your other method and not bother with this one.
What you really want to avoid is for your test to have too much knowledge of the code under test. You don't want to have to go through who knows how many layers in order to achieve what you want, because this leaves you with brittle tests which will need to change every time a code change happens.
So, change the way you think about the code and aim to make it testable.
Also, if you want to test for an exception, you must make sure you don't catch that exception as this will hide the actual thing.
I want to check if any method is called on a mock, the mock contains many method and i don't want to write many call in that way:
verify(mock).method1();
verify(mock).method2();
For the moment I'am using this hack, waiting to find a better solution:
boolean isThereAnyInerraction= false;
try {
Mockito.verifyZeroInteractions(maock);
} catch(NoInteractionsWanted e){
isThereAnyInerraction = true;
}
assertThat(isThereAnyInerraction).isTrue();
The method verifyZeroInteractions(mock) as it's name, verifies that no method is invoked on a mock.
I'm writing a selenium test and verifying the server behavior with mockito. Specifically, when a button is clicked, I want to make sure the page controller calls a particular method on a dependency which I've mocked.
Because it is a selenium test, I need to wait for the mock to be invoked in another thread, so I'm using mockito timeout.
verify(myMock, timeout(5000).times(1)).myMethod("expectedArg");
The trouble that I'm having is that myMethod is called many times... rather than waiting for an invocation that matches the expected arguments, timeout only waits for the first invocation.
If I use Thread.sleep(50000) rather than timeout(50000), it works as expected... but that's dirty so I'm hoping to avoid it.
How do I wait for myMethod to be invoked with the expected input?
If you are able to set a fixed number of calls to expect, it can be done with an ArgumentCaptor:
import static org.hamcrest.CoreMatchers.hasItem;
#Captor ArgumentCaptor<String> arg;
#Before
public void setUp() throws Exception {
// init the #Captor
initMocks(this);
}
#Test
public void testWithTimeoutCallOrderDoesntMatter() throws Exception {
// there must be exactly 99 calls
verify(myMock, timeout(5000).times(99)).myMethod(arg.capture());
assertThat(arg.getAllValues(), hasItem("expectedArg"));
}
Another way is to specify all the expected values to verify, but those need to be provided in the exact order that they are invoked. The difference to the above solution is that this doesn't fail even if the mock is additionally called with some non-verified arguments. In other words, no need to know the number of total invocations. Code example:
#Test
public void testWithTimeoutFollowingCallsDoNotMatter() throws Exception {
// the order until expected arg is specific
verify(callback, timeout(5000)).call("firstExpectedArg");
verify(callback, timeout(5000)).call("expectedArg");
// no need to tell more, if additional calls come after the expected arg
// verify(callback, timeout(5000)).call("randomArg");
}
This is not a super clean solution but you can do this (XX is the supposed return type here):
final CountDownLatch latch = new CountDownLatch(1);
doReturn(new Answer<XX>()
{
#Override
public XX answer(InvocationOnMock invocation)
{
latch.countDown();
return someInstanceOfXX;
}
}
).when(myMock).myMethod("expectedArg");
Then, to test if the method is called, do:
try {
assertTrue(latch.await(5L, TimeUnit.SECONDS));
} catch (InterruptedException e) {
// Urgh... Failed. Deal with it and:
Thread.currentThread().interrupt();
}
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*/);
}
});
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