I am practicing with mockito, but I am a bit stuck on how to test a method that depends on a call to method in a local object.
See the following example:
public class Worker {
public void work() {
Vodka vodka = new Vodka();
vodka.drink();
}
}
This worker, instead of doing his job, he likes drinking. But I want to add a test to prove that he drinks while he works. But there is no way of doing so, because I must verify that the method drink() is called when the method work is called. I think you agree with me, that this is impossible to test, so I need to break the dependency before starting to test.
Here is my first doubt, what do you think is the best way of breaking such dependency?
If I just change the scope of the vodka object to global, I think would not be good(I don't want to expose it to other parts of the class). I thought about creating a factory, something like this:
public class Worker {
private VodkaFactory vodkaFactory = new VodkaFactory();
public void work() {
Vodka vodka = vodkaFactory.getVodka();
vodka.drink();
}
}
I am not sure if I did break the dependency correctly, but what I want to do now, is test that the method drink() is called when work() is executed.
I tried this with no luck:
#Test
public void
does_the_worker_drink_while_working
() {
VodkaFactory vodkaFactory = mock(VodkaFactory.class);
Vodka vodka = mock(Vodka.class);
Worker worker = new Worker();
worker.work();
when(vodkaFactory.getVodka()).thenReturn(vodka);
verify(vodka,times(1)).drink();
}
I mock the factory and the when will detect that a new Vodka object is created by the factory. But then when I wan to verify that that method calls 1 time the method drink(), mockito tells me:
Wanted but not invoked:
vodka.drink();
-> at testing_void_methods_from_local_objects.WorkerSpecification.does_the_worker_drink_while_working(WorkerSpecification.java:22)
Actually, there were zero interactions with this mock.
I am not stubbing correctly or I am doing something wrong. Could you give me a hand completing this test and also clarify me what would be the best way of testing such untesteable methods?
I know mockito has a method called, doAnswer() which is used to mock a method call,do you think it can be useful in this case?
How should I use it?
UPDATE:
I am following the suggestions to get the when() called before the work() and also I am trying to allow the factory to be set from outside of the class:
#Test
public void
does_the_worker_drink_while_working
() {
VodkaFactory vodkaFactory = mock(VodkaFactory.class);
Vodka vodka = mock(Vodka.class);
Worker worker = new Worker();
when(vodkaFactory.getVodka()).thenReturn(vodka);
worker.work();
verify(vodka,times(1)).drink();
}
This is now the production code now:
public class Worker {
private VodkaFactory vodkaFactory;
public void work() {
Vodka vodka = vodkaFactory.getVodka();
vodka.drink();
}
public void setVodkaFactory(VodkaFactory vodkaFactory) {
this.vodkaFactory = vodkaFactory;
}
The exception that I get is the following:
java.lang.NullPointerException
at testing_void_methods_called_from_local_objects.Worker.work(Worker.java:9)
This is the line that says vodka.drink()
Sorry by I still confused on what is the problem.
Your worker creates his own factory class here:
private VodkaFactory vodkaFactory = new VodkaFactory();
The mock you are creating is completely detached from the worker instance and thus the lack of interaction. To make it work, factory has to be injected to worker from "the outside", say via constructor injection.
If this is legacy code, you could use reflection to replace private factory instance with mocked one.
As noted by JB Nizet in comment, your mock setup comes after work is already called. In order to make things right, inject mock and set it up before you call any code utilizing it.
You need to set your vodkaFactory:
#Test
public void
does_the_worker_drink_while_working() {
VodkaFactory vodkaFactory = mock(VodkaFactory.class);
Vodka vodka = mock(Vodka.class);
Worker worker = new Worker();
when(vodkaFactory.getVodka()).thenReturn(vodka);
//call your setter
worker.setVodkaFactory(vodkaFactory);
worker.work();
verify(vodka,times(1)).drink();
}
It is more comment than an answer. In addition to make factory an injectable dependency, you can also make sure to train your mock when(vodkaFactory.getVodka()).thenReturn(vodka); before interacting with it worker.work();
There is a logical error in the code you are trying to test. Because you have created VodkaFactory instance inside of the Worker class and moreover you have made that field private.
The best solution would be to pass a reference to VodkaFactory from outside of the class.
public class Worker {
private VodkaFactory vodkaFactory;
public void work() {
Vodka vodka = vodkaFactory.getVodka();
vodka.drink();
}
public void setVodkaFactory(VodkaFactory vf) {
vodkaFactory = vf;
}
}
Now, in your #Test you can pass your mocked VodkaFactory instance using setVodkaFactory setter.
The following is a complete JMockit unit test which exercises the Worker#work() method in isolation from the implementation of its Vodka dependency:
#Test
public void workTest(#Mocked final Vodka mockBeverage)
{
new Worker().work();
new Verifications() {{ mockBeverage.drink(); times = 1; }};
}
Related
I want to do Unit Tests for asynchronous methods in android. The result needs to be a "notified by observer's callback". Have a look at the below example. How can I write a unit test case for doSomething() method?
public interface IFooObserver {
void onResult(String result);
}
public class Foo {
private IFooObserver mObserver;
public Foo(IFooObserver observer) {
mObserver = observer;
}
public void doSomething() {
new Thread(new Runnable() {
#Override
public void run() {
// do something..
mObserver.onResult("hello, world!");
}
}).start();
}
}
Simply: don't use "bare metal" threads.
Use ExecutorServices instead - because that allows you to use dependency injection to turn your multi-threaded code into a single-threaded thing for testing - using a Same Thread Executor Service.
Example:
class Whatever {
private final ExecutorService service;
Whatever() { this ( Executors.newSingleThreadExecutor() ); }
Whatever(ExecutorService service) { this.service = service; }
void foo() {
service.submit ( ... whatever
The point is: when you are using a thread directly, you have no control whatsoever there. Most likely, that will lead to test cases that need complicated signaling, or worse: rely on calling sleep() here or there. And that is always bad - it increases the execution time of your tests; or, worse, you get the timing wrong; and occasionally your tests fail during regression. Because of different load on your test system; and threads showing different runtime characteristics.
So, long story short: if possible, avoid using threads directly; instead use the aforementioned concept to simply avoid multiple threads for testing.
I have a workflow which is set up by spring with a scope of "workflow". The below code would show the message straight away instead of waiting 60 seconds. I think it's because of the way I'm constructing my Helper class... how do I fix Asynchronous methods to work within another class?
public class MyWorkflowImpl implements MyWorkflowImpl {
private Helper helper = new Helper();
#Override
public do() {
Promise<Void> timer = getTimer(60); //seconds
helper.showMessage(timer);
}
}
public class Helper {
#Asynchronous
public showMessage(Promise<Void> timer) {
// show random message
}
}
The code is correct. #Asynchronous should work on any method of any class having that AspectJ preprocessor is applied to all classes that use it.
I'm new (very new) to Guice and JavaFX. I'm building an application that have a thread listening for socket connection and, after an event is received, the thread store value on ObservableArrayList() and the application will notify them to the user.
My problem is how to structure all this behaviour, and how to "share" the ObservableList from the thread and the JavaFX Controller.
I'm reading about Guice that could help to decouple the new creation of an object.
I've tried to setup something, but the #Inject property is null on my runnable task:
Guice Module:
public class AppGuiceModule extends AbstractModule{
#Override
protected void configure() {
bind(EventsDAO.class).toInstance(new EventsDAO());
}
}
EventsDAO (that have the ObservableArrayList )
#Singleton
public class EventsDAO {
private ObservableList<ScheduledEvent> localCache = FXCollections.observableArrayList();
public void addEvent(ScheduledEvent event) {
localCache.add(event);
}
public void removeEvent(ScheduledEvent event) {
this.localCache.remove(event);
}
}
With two this, i in my main i go to create the injector:
#Override
public void start(Stage stage) throws Exception {
Injector injector = Guice.createInjector(new AppGuiceModule());
Platform.setImplicitExit(false);
Thread t = new Thread(new EventsReceiverTask());
t.start();
.....
Now, in the Runnable object, i would to #Inject EventsDAO (to save new events) and #Inject this too in my Controller, adding to localCache a listener (yes localCache is private, i will provide a getter).
The runnable object:
public class EventsReceiverTask implements Runnable {
private static final int port = 4020;
#Inject
EventsDAO eventsDao; // This is null, why not injected ?
private ServerSocket serverSocket;
private Stage notificationStage;
public EventsReceiverTask() {
try {
this.serverSocket = new ServerSocket(port);
this.notificationStage = new Stage();
eventsDao.addEvent(new ScheduledEvent());
} catch (IOException ex) {
Logger.getLogger(EventsReceiverTask.class.getName()).log(Level.SEVERE, null, ex);
}
}
I dont know if this is the correct way to implement a "producer-consumer" in JavaFX, but i have no idea how to share that components, witthout creating tedious getter and setter, with all statics methods.
Your problem shows exactly why it is preferred not to use new in a dependency injected system, when possible.
Injections can only occur when the injection framework is the one creating the objects. When you call new, you are creating them, not the framework.
There are two ways to have Guice create an object for you:
Use injector.getInstance(Foo.class);
You want to use this as little as possible; generally speaking the only place you would use this method is inside your main method. Using this line elsewhere, makes it difficult to track down injections and understand the object graph. From Wikipedia:
With inversion of control, the flow depends on the object graph that is built up during program execution. Such a dynamic flow is made possible by object interactions being defined through abstractions.
Have Guice create your objects for you as injections.
This is exactly what the #Inject annotation does; instruct Guice to create the object for you in your bound classes.
Generally speaking, a class with a name like EventsReceiverTask is not the sort of top level class that you want to be creating in your main method. They have names more like EventService, to which you would inject a Provider<EventsReceiverTask> that is capable of creating new tasks for you, all of which will be injected with your EventsDAO properly.
Side note: you didn't ask about this, but when you do this, in your module:
bind(EventsDAO.class).toInstance(new EventsDAO());
You are overriding the scope of the binding that you attempted to specify with the #Singleton annotation in your class definition. If you want this object to actually be a singleton, you **must also specify the #Singleton binding in your module, e.g.
bind(EventsDAO.class).toInstance(new EventsDAO()).in(Singleton.class);
From the documentation:
If there's conflicting scopes on a type and in a bind() statement, the bind() statement's scope will be used. If a type is annotated with a scope that you don't want, bind it to Scopes.NO_SCOPE.
You never inject the member fields to the task object, so the value is null.
You need something like the inject part below so that Guice actually injects the field value. You might want further refactoring to make this better, but at the most basic level, Guice won't inject the field until you tell it to.
public void start(Stage stage) throws Exception {
Injector injector = Guice.createInjector(new AppGuiceModule());
Platform.setImplicitExit(false);
EventsReceiverTask task = new EventsReceiverTask();
// You need something like this so that Guice injects the members into the object.
injector.injectMembers(task);
Thread t = new Thread(task);
t.start();
....
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.
I'm looking for a way to verify with Mockito, that there wasn't any interaction with a given mock during a test. It's easy to achieve that for a given method with verification mode never(), but I haven't found a solution for the complete mock yet.
What I actually want to achieve: verify in tests, that nothing get's printed to the console. The general idea with jUnit goes like that:
private PrintStream systemOut;
#Before
public void setUp() {
// spy on System.out
systemOut = spy(System.out);
}
#After
public void tearDown() {
verify(systemOut, never()); // <-- that doesn't work, just shows the intention
}
A PrintStream has tons of methods and I really don't want to verify each and every one with separate verify - and the same for System.err...
So I hope, if there's an easy solution, that I can, given that I have a good test coverage, force the software engineers (and myself) to remove their (my) debug code like System.out.println("Breakpoint#1"); or e.printStacktrace(); prior to committing changes.
Use this :
import static org.mockito.Mockito.verifyZeroInteractions;
// ...
private PrintStream backup = System.out;
#Before
public void setUp() {
System.setOut(mock(PrintStream.class));
}
#After
public void tearDown() {
verifyZeroInteractions(System.out);
System.setOut(backup);
}
verifyZeroInteractions(systemOut);
As noted in comments, this doesn't work with a spy.
For a roughly equivalent but more complete answer, see the answer by gontard to this question.
Since the original correct answer, verifyZeroInteractions has been deprecated, use verifyNoInteractions instead:
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
public class SOExample {
#Test
public void test() {
Object mock = mock(Object.class);
verifyNoInteractions(mock);
}
}
You could try a slightly different tack:
private PrintStream stdout;
#Before public void before() {
stdout = System.out;
OutputStream out = new OutputStream() {
#Override public void write(int arg0) throws IOException {
throw new RuntimeException("Not allowed");
}
};
System.setOut(new PrintStream(out));
}
#After public void after() {
System.setOut(stdout);
}
If you preferred, you could switch the anonymous type for a mock and verify as Don Roby suggests.
One way of solving this problem is to refactor the class that you're testing, to allow for the injection of a PrintStream that can be used for output. This will let you unit test it, without relying on the behaviour of the System class. You could use a package-private constructor for this injection, since you'll only ever use it from the corresponding test class. So it might look something like this.
public class MyClass{
private PrintWriter systemOut;
public MyClass(){
this(System.out);
}
MyClass(PrintWriter systemOut){
this.systemOut = systemOut;
// ...any other initialisation processing that you need to do
}
}
and within the class itself, use the systemOut variable instead of System.out wherever you call the latter.
Now, within the test class, make a mock PrintStream, and pass it to the package-private constructor, to get the object that you're going to test. Now you can run any actions you like from your tests, and use verify to check their effects on your mock PrintStream.