How to verify if any method is called on a mock - java

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.

Related

Mock External method calls from class In Juints

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

How can I get some value in inner class in java?

I want to return some value depend on some value in inner class:
public boolean rename(File file) {
new OnResultListener() {
#Override
public void onResult(AsyncResult<CharSequence> result) {
// some codes
// Here is what I want to do
if (succeed) {
// rename return true
} else {
// rename return false
}
}
}
}
You can't and it does not make sense. These are two distinct functions that may very well be called on different threads. What you have to do, if you insist on returning something, is that the "rename" function itself should receive a callback as a parameter that gets called upon success. That is, if the downstream call is asynchronous then the ones calling it should be too.
An alternative would be to have a the calling function ("rename" in this case assuming it calls the function that notifies the OnResultListener) to wait on some mutex. Then, in the nested method upon receiving a result, you set some flag and then call notify() which would wake the thread held by the wait.

how to unit test this threaded code

I have a class that normally runs in a thread that processes data forever until another thread invokes stop() on it. The problem I have is that the unit test gets stuck in the main loop since the test is single threaded and I want to keep it that way. How can I unit test this without polluting the code? this class is part of a critical system and needs to be as simple and efficient as possible so I want to avoid unit testing hacks in the code
public class MyClass implements Runnable {
boolean running;
public void run() {
//foo is injected from the outside
foo.start();
work();
foo.end();
}
public void work() {
running = true;
while(running) { //main loop
bar.process(); //bar is injected from the outside
}
}
public void stop() {
running = false;
}
}
Basically what I'm doing in the test is mocking out foo and bar and I call run() from the unit test, where later I verify in the bar mock whether process was actually called. I also verify that in the foo mock start() and end() got called. The problem is that because I really want to keep the test single threaded, the test thread gets stuck forever in the while(running) loop.
Some things I have tried and don't like
add some VM property to trigger a break at the end of the iteration of the main loop. The problem with this is that as mentioned, this code is very critical and I want to keep the code clear of unit-testing clutter. I don't want production code evaluating in every iteration some VM property that I only use at development time
use the bar mock to invoke stop() on its call of process(). Mockito doesn't like the fact that I call another class' method and throws an exception
externalize the control of the mainloop. so instead of checking a boolean in the while, I call a method that returns whether to continue or not. And this loop-control object can be injected from the outside, that way in the unit test i can make the control method return true and then false to get a single iteration out of the loop. This complexifies the code quite a bit and makes it unnatural and harder to read plus it only would make any sense in a unit test context
Are there any other suggestions or common patterns to test Runnables, or maybe a better way to write my code so that testing it is easier?
I suggest making a change which would both make your code more by-the-book and allow breaking out in a single thread:
while (!Thread.currentThread().isInterrupted() && running) {
bar.process();
}
You can call Thread.currentThread().interrupt() before you run this code; the thread's interrupted flag will be set and the method isInterrupted() will return true.
This is more by-the-book because it makes your main loop participate in Java's interruption mechanism.
Create an interface for the class of bar that only contains the method process. Your MyClass seems generic enough so that this would be OK. Then, instead of mocking bar, create your own implementation dummy (or mock, whatever you like to call it). This will then call the stop method and your process method is only called once. You can check whether BarMock.process was called with an assertion using its isCalled method. Also, I would suggest an isRunning method for your MyClass so that you can check whether it was stopped.
public interface Processable {
public void process();
}
public class BarMock implements Processable {
private MyClass clazz;
private boolean called;
public BarMock(MyClass clazz) {
this.clazz = clazz;
called = false;
}
#Override
public void process() {
// you can assertTrue(clazz.isRunning()) here, if required
called = true;
clazz.stop();
}
public boolean isCalled() {
return called;
}
}
public class MyClass implements Runnable {
boolean running;
public void run() {
// foo is injected from the outside
foo.start();
work();
foo.end();
}
public void work() {
running = true;
while (running) { // main loop
bar.process(); // bar is injected from the outside
}
}
public void stop() {
running = false;
}
public boolean isRunning() {
return running;
}
}
I think this method has three advantages over the one suggested by William F. Jameson, but also disadvantages:
Advantages:
You can test whether your process method was actually called
You don't have to add code that you never use during the actual program run
You can test whether the stop method really stops
Disadvantages:
You have to introduce an interface
Need to test BarMock class, too
That said, I'd still prefer introducting the interface, since it doesn't pollute your code too much and therefore is a small price to pay.

Mockito: wait for an invocation that matches arguments

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();
}

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