Calling callbacks with Mockito - java

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*/);
}
});

Related

Byte Buddy not preserving return value when .andThen used

I am trying to use Byte Buddy to execute some additional logic when a method is done. Here is the sample code:
T proxyClient = JAXRSClientFactory.fromClient(client, classType, true);
this.configureHttpConduit(conduit, invocationTimeout);
Class buddy = new ByteBuddy()
.subclass(classType)
.method(ElementMatchers.isAnnotatedWith(Path.class))
.intercept(MethodDelegation.to(proxyClient)
.andThen(MethodCall.run(new CloseConnection())))
.make()
.load(this.getClass().getClassLoader(),
Default.INJECTION)
.getLoaded();
return (T) buddy.newInstance();
static class CloseConnection implements Runnable {
void close() {
System.out.println("close connection called");
}
#Override
public void run() {
close();
}
}
When I chain the delegation with the .andThen call, the original caller to this instance loses the return values that was from the "proxyClient" object which it used to invoke a method call on it earlier. Am I using Byte Buddy wrong?
Basically I want to add some additional logic to the end of a method (inside the original method or adding another method call does not matter), but at the same time preserving the return value of the original method call.
This is by design. For every Implementation that you chain via andThen, Byte Buddy expects an empty stack for the next block. Thus, the last implementation is responsible for the return.
The idea of Byte Buddy is to put as much logic as possible into the interceptor. I would suggest to you to write your own interceptor that invokes the delegate and then invokes the close connection. This gives you also full control over the call conditions like closing in a finally block:
public class MyInterceptor<T> {
final T proxyClient;
#RuntimeType
public Object intercept(#Origin Method method,
#AllArguments Object[] args) throws Throwable {
try {
return method.invoke(proxyClient, args);
} finally {
// do your completion logic here
}
}
}
This can of course be improved in terms of performance. Have a look at the #Pipe annotation for that.

Any design patterns for handling the following case in Java?

I'm new to Java & its design patterns, I have a scenario like this:
Method 1 calls Method 2.
Method 2 looks like the following:
public String createUser(String username, String password) {
someApi.do(config -> {
//code here with respect to someApi.
});
}
now the trick is I need to return the value to caller which is method 1. If there are no exceptions then that is fine. However the code block inside do can throw exception, which will be handled in a separate listener class like this:
public class TestListener implements SomeApiListener {
#Override
public void exception(Throwable cause) {
}
}
Now how should I send back the exception to method 1 from this listener? I'm really confused.
it's not clear what that API do, where the listener is assigned, and what other methods it has, like if there is also onSuccess() ?
what i got from this, is that, you are dealing with async call, which usually do not return a value directly, it deals with a CallBack which in your case is SomeApiListener
So, ... I would make createUser() receives extra arg, SomeApiListener, pass the listener as anonymous inner class (with implementation) when calling the method (from caller).
ex,
public String createUser(String username, String password, SomeApiListener listener) {
someApi.do(config -> {
//code here with respect to someApi.
//somewhere here you are creating a TestListener ?,
//well... don't, and use the one passed from caller (listener)
});
}
Caller part will look like this:
public void method1(){
//..some code ...
createUser(username, password, new SomeApiListener(){
#Override
public void exception(Throwable cause) {
//handle exception...
}
#Override
public void success(Response response) {
//handle response ...
}
});
}
Note: you can still pass TetstListern, if you want, in that case you will have to have a physical class (local class) defined and instantiated, the anonymous-inner-class is somehow a shortcut for that, you don't create a local class, just pass it as an arg.
You can't, at least not in any simple way. I'd expect the documentation for your someApi to demonstrate some common use cases, with exception handling included. If you're combining different ways of programming ("normal" java & functional programming), you can get into tricky situations.
Based on the information you've given, a clumsy solution could look something like this (code obviously not fit for compilation):
public class MyClass implements SomeApiListener {
private Throwable e;
public void exception(Throwable cause) {
e = cause;
}
public void method1() {
createUser("foo", "bar");
if(e != null) {
// Exception was thrown, do something with it
}
}
}
However this is in no way a recommendation. It's clumsy, hacky and bad in every way. A better solution would involve not trying to send the exception back to method1, but instead to modify your code to work in the way that someApi expects.
It depends on your design on how to handle exceptions. Normally, if the method 2 is an utility method then throw the exception back to method 1 and let it handle the exception. Else, if method 2 understands the use case for which it is called then handle the exception there. There are no hard and fast rules, but keep the utility classes clean and send the exception back to the caller so that caller can handle it.

Observable which does not pass anything in onNext()

I would need an Observable, for example to provide a system clock, which does not need to pass anything in onNext(). I couldn't find a signature that would allow me to do that.
Sure, I could use any object and then pass null, but that doesn't make much sense. So my question is if there is a better way to do that.
Observable.create(new Observable.OnSubscribe<Anyobject>() { // use any object in the signature
#Override public void call(Subscriber<? super Anyobject> subscriber) {
subscriber.onNext(null); // then pass null
subscriber.onCompleted();
}
})
You don't need to call onNext if your Observable doesn't emit anything.
You could use Void in your signature and do something like
Observable<Void> o = Observable.create(new Observable.OnSubscribe<Void>() {
#Override
public void call(Subscriber<? super Void> subscriber) {
// Do the work and call onCompleted when you done,
// no need to call onNext if you have nothing to emit
subscriber.onCompleted();
}
});
o.subscribe(new OnCompletedObserver<Void>() {
#Override
public void onCompleted() {
System.out.println("onCompleted");
}
#Override
public void onError(Throwable e) {
System.out.println("onError " + e.getMessage());
}
});
You can define an OnCompletedObserver to simplify your Observer callback so that you don't have to override the onNext since you don't need it.
public abstract class OnCompletedObserver<T> implements Observer<T> {
#Override
public void onNext(T o) {
}
}
If I've understood what you're asking then this should do the trick.
If you need something to be passed to onNext() before onCompleted() is called:
Observable.<Void>just(null)
If you only need onCompleted() to be called:
Observable.empty()
RxJava 2 Wiki:
RxJava 2.x no longer accepts null values and the following will yield
NullPointerException immediately or as a signal to downstream.
...
This means that Observable<Void> can no longer emit any values but
only terminate normally or with an exception. API designers may
instead choose to define Observable<Object> with no guarantee on what
Object will be (which should be irrelevant anyway)
It means that you can't use Void and do Observable.just(null).
Use Object or some other simple type instead:
Observable.just(new Object());
Starting with RxJava 2, the propper way to do this is to use a Completable
From the docs:
Represents a deferred computation without any value but only
indication for completion or exception. The class follows a similar
event pattern as Reactive-Streams: onSubscribe (onError|onComplete)?
One of the light solutions is to use Observable<Boolean>
And then onNext(Boolean.TRUE) which you then just ignore.
But probably you shouldn't use Observable in that case.
Consider using Completable instead
I don't know this will helps you or not.
The code written in RxSwift.
// Create an observable and emit somethings
let myObservable = Observable<Void>.create{ observer in
observer.on(.next(Void()))
return Disposables.create()
}
// Observer subscribe changes
myObservable.subscribe(onNext: {
_ in
print("Hello")
}).disposed(by: disposeBag)
Or use the Variable object
// Create a Variable object that contanins nothing
var myValueWatcher:Variable<Void> = Variable<Void>(Void())
// Observer subscribe changes
myValueWatcher.asObservable().skip(1).subscribe(onNext: {
_ in
print("Changes!")
}).disposed(by: disposeBag)
// The emit code
myValueWatcher.value = Void()

How to handle the situation where a bean requires a server call as part of its initialiation

I have the folowing constructor...
#Inject
public EditorPresenter(final EventBus eventBus, final MyView view, final Provider<DataProvider> provider) {
DataProvider provider = provider.get();
provider.getInitData().fire(new Receiver<List<DataElement>>() {
#Override
public void onSuccess(List<DataElement> response) {
LOG.info("seting feed types to {}", response);
EditorPresenter.this.data = response;
}
});
}
This constructor sets the class field data to the values returned in the request factory call.
The problem is this data requires a call to the server and is thus asynchronous.
And this field needs to be set when the constructor returns as other objects/beans depend on it (I'm having subsequent errors that depend on data being initalised).
What is the most efficient and light weight way of handling this scenario with Gin?
I'm hoping that there is something built into GIN that handles this scenario gracefully.
GQuery Promise solves this kind of situations:
Something like:
public void yourMethod(....) {
....
getDataFromServer(provider).then(processData)
.done(new Function() { public void f(){
continueYourFlow();
}})
.fail(new Function() { public void f(){
handleError();
}});
}
protected Promise getDataFromServer(final Provider<DataProvider> provider) {
return new PromiseRF(provider.getInitData());
}
Function proccessData = new Function() { public void f() {
List<DataElement> data = arguments(0);
//do something with your data
}};
should work. If not, just ask!
There is something wrong in your approach. You shouldn't hold all your application waiting for server.
If I understand, some data from server is required before client is initialized. Maybe you should put them in your host page? Or move initialization of presenters to other methods and execute these methods by events.
It might be best to not initialize the rest of your app yet. I'm not sure how your initialization is laid out, but I would not initialize anymore after you inject the instance of your EditorPresenter class.
When your onSuccess call gets triggered, fire an event or call a method that picks up where you would have left off. If you think it will be a while you could throw up a wait screen or some such.

Java remove listener, when callback is executed

I just can't figure out how to remove listener when I have some event executed. I have some leaking issue using websockets, and this can probaly fix it.
final WebSocket w = asyncHttpClient.prepareGet(url)
.execute(new WebSocketUpgradeHandler.Builder().build())
.get();
w.addWebSocketListener(new WebSocketTextListener() {
public void onMessage(String message) {
listener.onMessage(responseMessage);
// Here is the place I want to do my w.removeWebSocketListener(l);
}
#Override
public void onFragment(String s, boolean b) {
}
public void onOpen(WebSocket websocket) {
}
#Override
public void onClose(WebSocket webSocket) {
}
#Override
public void onError(Throwable throwable) {
}
});
The problem is when I create WebSocketTextListener lis = new .... and passing in there is something like one object need other object and other object is dependent on this, and I'm still now allowed to do what I want.
Looks like it is something simple, but can't figure out.
Normally event listeners can be removed with a removeXXXListener method. But it requires that you provide the exact same event listener instance as parameter. You can store the event listener and later remove it using the same reference. But since you, in the onMessage message already are inside the scope of the event listener, using this should work.
Try something like
listener.onMessage(responseMessage);
// Here is the place I want to do my w.removeWebSocketListener(l);
w.removeWebSocketListener(this);
Using "this" in anonumous inner class is the way to solve problem. But, it is muck better to refactor code, to avoid using anonumous classes, for testability and better understanding.

Categories