Optional callbacks [duplicate] - android

This question already has answers here:
Optional Methods in Java Interface
(13 answers)
Closed 8 years ago.
I have the interface
public interface UserResponseCallback {
void starting();
void success();
void error(String message);
void finish();
}
Is it possible to make the methods optional?

A non-abstract class must implement every abstract method it inherited from interfaces or parent classes. But you can use that to allow you to implement only certain required parts as long as you can live with the fact that you can no longer implement the interface at will.
You would create an abstract class that implements the optional part of the interface with empty default implementations like
abstract class UserResponseCallbackAdapter implements UserResponseCallback {
#Override
public void starting() { /* nothing */ }
#Override
public void success() { /* nothing */ }
#Override
public void error(String message) { /* nothing */ }
// finish() intentionally left out
}
You can now create subclasses that have to implement just the required parts while they still can implement the optional parts.
class User {
private final UserResponseCallback callback = new UserResponseCallbackAdapter() {
#Override
public void finish() {
// must be implemented because no empty default in adapter
}
#Override
public void starting() {
// can be implemented
}
};
void foo() {
// can be used like every other UserResponseCallback
CallbackManager.register(callback);
}
}
This technique is for example used by AWT event callbacks e.g. MouseAdapter. It starts getting worth the extra effort once you use the callback multiple times since the optional part needs to be implemented only once instead of every time.
Your next option is top split the interface into two. Your conceptional problem is that your interface contains more than it should have, compare Interface Segregation Principle. You could split it either into two or more actually independent interfaces or you could extend a required base interface with optional extra features like
interface UserResponseCallbackBase {
// this is the only required part
void finish();
}
interface UserResponseCallbackFull extends UserResponseCallbackBase {
void starting();
void success();
void error(String message);
void finish();
}
To use that kind of hierarchical callback you would probably add some intelligence to whatever class manages the callbacks and let it check whether or not a callback wants a certain callback based on it's type.
For example like
class CallbackManager {
private List<UserResponseCallbackBase> mCallbacks = new ArrayList<UserResponseCallbackBase>();
public void register(UserResponseCallbackBase callback) {
mCallbacks.add(callback);
}
public void notifyStarting() {
for (UserResponseCallbackBase callback : mCallbacks) {
// check if callback is of the extended type
if (callback instanceof UserResponseCallbackFull) {
((UserResponseCallbackFull)callback).starting();
} // else, client not interested in that type of callback
}
}
}
That way you can freely choose which type of interface you want to implement and the calling code checks whether or not you want to get a callback. I.e. if you register(new UserResponseCallbackFull() {...}) you would be notified about starting(), if you were to register(new UserResponseCallbackBase() {...}) you would not.
This technique is used in Android with ComponentCallbacks2 which you register via Context#registerComponentCallbacks(ComponentCallbacks) - it takes both a "simple" ComponentCallbacks and the extended version and checks what type you gave it.

No, that's not possible in Java.
Have a look at this question that comes to the same conclusion: Optional Methods in Java Interface

No.
Use a dummy implementation and override if needed.

Related

visitor pattern with network call - best way to update android UI from vistor

I am using the visitor pattern to abstract payment processing away from the UI code in android. I have some doubts on what i should pass into the visitor constructor inorder for the view to get a call back once its done processing the payment.
Let me show you what i have so far:
i am dealing with 2 payment systems, thus two payment strategies (brainTree and Stripe):
public class BrainTreePaymentStrategy implements IVisitable {
#Override
public void makePayment() {
}
#Override
public void accept(Visitor v) {
}
}
public class StripePaymentStrategy implements IVisitable {
#Override
public void makePayment() {
}
#Override
public void accept(IVisitor v) {
}
}
public interface IVisitable {
void makePayment();
void accept(IVisitor v);
}
public interface IVisitor {
//list out all the classes the visitor can visit now
void visit(StripePaymentStrategy stripePaymentStrategy);
void visit(BrainTreePaymentStrategy brainTreePaymentStrategy);
}
//now critical, lets create a real concrete visitor that can actually do the work:
public class PaymentStrategyVistor implements IVisitor {
#Override
public void visit(StripePaymentStrategy stripePaymentStrategy) {
//process the braintree payment here, but how to give call back to UI ?
}
#Override
public void visit(BrainTreePaymentStrategy brainTreePaymentStrategy) {
//process the braintree payment here, but how to give call back to UI ?
}
}
i am using uncle bob's clean architecuture so my network calls are through usecases and also im using mvp for my presentation layer so i have access to presenter and usecase if needed.
So again my question is regarding PaymentStrategyVistor class, what do you think if i passed in the presenter as a constructor parameter. i for example , could then call presenter.doBrainTreePayment("someToken"); i could do that in the visitors visit(BrainTreePaymentStrategy brainTreePaymentStrategy) method. is this how you all would do it ?
Your suggestion (passing the presenter to the constructor of each visitor) seems to be totally fine.
Looking from clean architecture perspective this all is fine as long as u do not violate the dependency rule. so if ur strategy and visitors live in the "interface adapter layer" u can easily pass the presenter. on the other hand if ur strategy/visitor belong to the "use cases layer" than passing the presenter would violate the dependency rule and u should not do it.
For a more detailed discussion on presenters in clean architecture see my blog post: https://plainionist.github.io/Implementing-Clean-Architecture-Controller-Presenter/

android interface make callback function optional

I have a simple class with an interface enabled and works proper when used.
interface interfacename{
void function1();
void function2();
}
public class asyncfunction(){
public interfacename listener;
...
onasyncStart( ... ){
listener.function1();
}
...
...
onasyncComplete( ... ){
listener.function2();
}
}
public myclass(){
....
....
methodcall(new interfacename(){
#Override
public void function1(){
// executes proper
}
#Override
public void function2(){
// executes proper
}
}
}
So the above method works proper.
But i want to call only the function1() sometimes and only function2() when needed.
I don't want both methods to be implemented always. The code looks big and im not sure if it slows down code or not ( not on the milli second level btw ) but it would be really nice if there was another way to have the option to execute particular call backs when needed.
It sounds like you're really looking at splitting up your interface into multiple interfaces, and change the method that accepts this interface as a parameter, so that it will instead accept the interface that it requires (e.g. InterfaceOne) in order to call a method in that interface (e.g. function1()). Another method might want to call function2(), in which case it will accept an argument of type InterfaceTwo.
If however you need to always call both methods of the interface in your method, but you don't always need to call any code in the methods of that interface, what you're looking at instead is the following.
Instead of creating a new anonymous class of type interfacename, you could use a base class with empty method bodies, and simply override the ones you need. Methods implemented by the abstract base class are essentially optional, while those that are not implemented are required methods.
This is a very common pattern in Java development.
public interface InterfaceName {
void function1();
void function2();
}
public abstract class BaseInterfaceName implements InterfaceName {
public void function1() {
}
public void function2() {
}
}
public class MyClass {
public void myMethod() {
myMethodWithInterface(new BaseInterfaceName() {
#Override
public void function2() {
System.out.println("function2");
}
})
}
public void myMethodWithInterface(InterfaceName intf) {
intf.function1();
intf.function2();
}
}
A possible solution is the one explained by #Nicklas.
But, if you use Java 8, you can use the default method. So you can declare your interface in this way:
public interface InterfaceName {
default void function1(){ /* do nothing */}
default void function2(){ /* do nothing */}
}
So, you can avoid implementing the methods, since you are providing a default implementation. In my example the default is to do nothing, but of course, you can personalize them.

Mortar + Flow with third party libraries hooked to activity lifecycle

Some third party libraries use hooks into the activity lifecycle to work correctly - for instance, the Facebook SDK (https://developers.facebook.com/docs/android/login-with-facebook/).
I'm having some trouble figuring out how to reconcile this model cleanly with a single-activity flow+mortar setup.
For instance, if I want to use Facebook login as part of a login Flow (w/ FlowView/FlowOwner), but not otherwise in the activity, what's the smartest way to pull this off if you need hooks for that particular flow in onCreate, onResume, onPause, onDestroy, onSaveInstanceState, onActivityResult, etc?
It's not immediately obvious what the cleanest path is - create an observable for each lifecycle activity stage and subscribe the flow to it? Seems like that path quickly devolves to the same Android lifecycle if you're not careful. Is there a better way?
I love the single activity model, and I'd really like to keep everything managed by flow/mortar and not activities, if possible. Or am I thinking about this in a way that is fundamentally making it more difficult than it should be?
We haven't had a need for start and stop so far, but do have a few spots that rely on pause and resume. We use an ActivityPresenter as you suggest, but avoid any kind of universal superclass. Instead it exposes a service that interested presenters can opt in to. This kind of hookup need is why the onEnterScope(Scope) method was added. Here's the code.
First, have the activity implement this interface:
/**
* Implemented by {#link android.app.Activity} instances whose pause / resume state
* is to be shared. The activity must call {#link PauseAndResumePresenter#activityPaused()}
* and {#link PauseAndResumePresenter#activityResumed()} at the obvious times.
*/
public interface PauseAndResumeActivity {
boolean isRunning();
MortarScope getMortarScope();
}
And have it inject the presenter and make the appropriate calls:
private boolean resumed;
#Inject PauseAndResumePresenter pauseNarcPresenter;
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pauseNarcPresenter.takeView(this);
}
#Override public boolean isRunning() {
return resumed;
}
#Override protected void onResume() {
super.onResume();
resumed = true;
pauseNarcPresenter.activityResumed();
}
#Override protected void onPause() {
resumed = false;
super.onPause();
pauseNarcPresenter.activityPaused();
}
#Override protected void onDestroy() {
pauseNarcPresenter.dropView(this);
super.onDestroy();
}
Now interested parties can inject a registrar interface to opt-in to pause and resume calls, without subclassing anything.
/**
* Provides means to listen for {#link android.app.Activity#onPause()} and {#link
* android.app.Activity#onResume()}.
*/
public interface PauseAndResumeRegistrar {
/**
* <p>Registers a {#link PausesAndResumes} client for the duration of the given {#link
* MortarScope}. This method is debounced, redundant calls are safe.
*
* <p>Calls {#link PausesAndResumes#onResume()} immediately if the host {#link
* android.app.Activity} is currently running.
*/
void register(MortarScope scope, PausesAndResumes listener);
/** Returns {#code true} if called between resume and pause. {#code false} otherwise. */
boolean isRunning();
}
Have the client presenter implement this interface:
/**
* <p>Implemented by objects that need to know when the {#link android.app.Activity} pauses
* and resumes. Sign up for service via {#link PauseAndResumeRegistrar#register(PausesAndResumes)}.
*
* <p>Registered objects will also be subscribed to the {#link com.squareup.otto.OttoBus}
* only while the activity is running.
*/
public interface PausesAndResumes {
void onResume();
void onPause();
}
And hook things up like this. (Note that there is no need to unregister.)
private final PauseAndResumeRegistrar pauseAndResumeRegistrar;
#Inject
public Presenter(PauseAndResumeRegistrar pauseAndResumeRegistrar) {
this.pauseAndResumeRegistrar = pauseAndResumeRegistrar;
}
#Override protected void onEnterScope(MortarScope scope) {
pauseAndResumeRegistrar.register(scope, this);
}
#Override public void onResume() {
}
#Override public void onPause() {
}
Here's the presenter that the activity injects to make it all work.
/**
* Presenter to be registered by the {#link PauseAndResumeActivity}.
*/
public class PauseAndResumePresenter extends Presenter<PauseAndResumeActivity>
implements PauseAndResumeRegistrar {
private final Set<Registration> registrations = new HashSet<>();
PauseAndResumePresenter() {
}
#Override protected MortarScope extractScope(PauseAndResumeActivity view) {
return view.getMortarScope();
}
#Override public void onExitScope() {
registrations.clear();
}
#Override public void register(MortarScope scope, PausesAndResumes listener) {
Registration registration = new Registration(listener);
scope.register(registration);
boolean added = registrations.add(registration);
if (added && isRunning()) {
listener.onResume();
}
}
#Override public boolean isRunning() {
return getView() != null && getView().isRunning();
}
public void activityPaused() {
for (Registration registration : registrations) {
registration.registrant.onPause();
}
}
public void activityResumed() {
for (Registration registration : registrations) {
registration.registrant.onResume();
}
}
private class Registration implements Scoped {
final PausesAndResumes registrant;
private Registration(PausesAndResumes registrant) {
this.registrant = registrant;
}
#Override public void onEnterScope(MortarScope scope) {
}
#Override public void onExitScope() {
registrations.remove(this);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Registration that = (Registration) o;
return registrant.equals(that.registrant);
}
#Override
public int hashCode() {
return registrant.hashCode();
}
}
}
So I've been porting a personal app over to flow and mortar to evaluate it for businesses use. I haven't encountered a scenario where I HAD to have the entire activity lifecycle yet, but as things stand with the current version of flow (v0.4) & mortar (v0.7), this is something I think you will have to creatively solve for yourself. I've recognized this as a potential problem for myself and have put some thought of how to overcome it:
I would also like to note that I haven't actually used the Facebook SDK. You will have to choose the best method for yourself.
You could post events from the activity for each Activity life cycle event. You essentially mentioned this approach using RXJava's Observables. If you really really wanted to use RXJava, you could use a PublishSubject for this, but I'd probably go with simple events from an EventBus you could subscribe to. This is probably the easiest approach.
You could also, depending on how the Facebook SDK works, possibly inject the Facebook SDK component in the activity, and from there initialize it. Then also inject the Facebook SDK component into your view to be used. Flow and Mortar's entire system is deeply integrated into dependency injection after all? This approach is also fairly simple, but depending on how the Facebook SDK works it probably isn't the best option. If you did go this route, you'd need to heed my warning at the bottom of this post.
This brings us to my last idea. Square had a similar problem when they needed access to an Activity's ActionBar in it's sub-views/presenters. They exposed access to the ActionBar in their sample app via something they called the ActionBarOwner.java. They then implement the ActionBarOwner interface and give an instance of itself in the DemoActivity.java. If you study how they implemented this and share it through injection, you could create a similar class. AcivityLifecycleOwner or something (the name needs work), and you could subscribe to callbacks on it from a presenter. If you decide to go down this route, and aren't careful you can easily end up with a memory leak. Any time you would subscribe to any of the events (I'd recommend you subscribe in the presenter), you'd need to make sure you unsubscribe in the onDestroy method as well. I've created a short untested sample of what I mean for this solution below.
No matter which approach you use, you'll probably need to make sure your onCreate and onDestroy methods actually come from your presenter, and not the exact events from the activity. If you are only using the sdk on a single view, the activity's onCreate has been called long before your view is instantiated probably, and the onDestroy for the Activity will be called after your view is destroyed. The presenter's onLoad and onDestroy should suffice I think, however I haven't tested this.
Best of luck!
Untested code example for solution #3:
All your presenters could extend this class instead of ViewPresenter and then override each method you wanted events for just like you would in an activity:
public abstract class ActivityLifecycleViewPresenter<V extends View> extends ViewPresenter<V>
implements ActivityLifecycleListener {
#Inject ActivityLifecycleOwner mActivityLifecycleOwner;
#Override protected void onLoad(Bundle savedInstanceState) {
super.onLoad(savedInstanceState);
mActivityLifecycleOwner.register(this);
}
#Override protected void onDestroy() {
super.onDestroy();
mActivityLifecycleOwner.unregister(this);
}
#Override public void onActivityResume() {
}
#Override public void onActivityPause() {
}
#Override public void onActivityStart() {
}
#Override public void onActivityStop() {
}
}
Activity Lifecycle owner that would be injected into the activity and then hooked up to the corresponding events. I purposely didn't include onCreate and onDestroy, as you presenter's wouldn't be able to get access to those events as they wouldn't be created or they would already be destroyed. You'd need to use the presenters onLoad and onDestroy methods in place of those. It's also possible that some of these other events wouldn't be called.
public class ActivityLifecycleOwner implements ActivityLifecycleListener {
private List<ActivityLifecycleListener> mRegisteredListeners
= new ArrayList<ActivityLifecycleListener>();
public void register(ActivityLifecycleListener listener) {
mRegisteredListeners.add(listener);
}
public void unregister(ActivityLifecycleListener listener) {
mRegisteredListeners.remove(listener);
}
#Override public void onActivityResume() {
for (ActivityLifecycleListener c : mRegisteredListeners) {
c.onActivityResume();
}
}
#Override public void onActivityPause() {
for (ActivityLifecycleListener c : mRegisteredListeners) {
c.onActivityPause();
}
}
#Override public void onActivityStart() {
for (ActivityLifecycleListener c : mRegisteredListeners) {
c.onActivityStart();
}
}
#Override public void onActivityStop() {
for (ActivityLifecycleListener c : mRegisteredListeners) {
c.onActivityStop();
}
}
}
Now you need to hook the lifecycle owner to the activity:
public class ActivityLifecycleExample extends MortarActivity {
#Inject ActivityLifecycleOwner mActivityLifecycleOwner;
#Override protected void onResume() {
super.onResume();
mActivityLifecycleOwner.onActivityResume();
}
#Override protected void onPause() {
super.onPause();
mActivityLifecycleOwner.onActivityPause();
}
#Override protected void onStart() {
super.onStart();
mActivityLifecycleOwner.onActivityStart();
}
#Override protected void onStop() {
super.onStart();
mActivityLifecycleOwner.onActivityStop();
}
}

Best practice to implement Retrofit callback to recreated activity?

I'm switching to Retrofit and trying to understand proper architecture for using it with async callbacks.
For example I have an interface:
interface RESTService{
#GET("/api/getusername")
void getUserName(#Query("user_id") String userId,
Callback<Response> callback);
}
And I run this from main activity:
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("WEBSITE_URL")
.build();
RESTService api = restAdapter.create(RESTService.class);
api.getUserName(userId, new Callback<Response> {...});
Then user rotates the device and I have newly created activity... What was happen here? How can I get response to the new activity (I assume that api call in background will execute longer than first activity life). Maybe I must use static instance of callback or what? Please show me the right way...
Use otto.
There are a lot of samples to mix otto and retrofit, for example https://github.com/pat-dalberg/ImageNom/blob/master/src/com/dalberg/android/imagenom/async/FlickrClient.java
Or read this post http://www.mdswanson.com/blog/2014/04/07/durable-android-rest-clients.html
It answers on almost all questions
For potential long running server calls i use an AsyncTaskLoader. For me, the main advantage of Loaders are the activity-lifecycle handling. onLoadFinished is only called if your activity is visible to the user. Loaders are also shared between activity/fragment and orientation changes.
So i created an ApiLoader which uses retrofits synchronous calls in loadInBackground.
abstract public class ApiLoader<Type> extends AsyncTaskLoader<ApiResponse<Type>> {
protected ApiService service;
protected ApiResponse<Type> response;
public ApiLoader(Context context) {
super(context);
Vibes app = (Vibes) context.getApplicationContext();
service = app.getApiService();
}
#Override
public ApiResponse<Type> loadInBackground() {
ApiResponse<Type> localResponse = new ApiResponse<Type>();
try {
localResponse.setResult(callServerInBackground(service));
} catch(Exception e) {
localResponse.setError(e);
}
response = localResponse;
return response;
}
#Override
protected void onStartLoading() {
super.onStartLoading();
if(response != null) {
deliverResult(response);
}
if(takeContentChanged() || response == null) {
forceLoad();
}
}
#Override
protected void onReset() {
super.onReset();
response = null;
}
abstract protected Type callServerInBackground(SecondLevelApiService api) throws Exception;
}
In your activity you init this loader like this:
getSupportLoaderManager().initLoader(1, null, new LoaderManager.LoaderCallbacks<ApiResponse<DAO>>() {
#Override
public Loader<ApiResponse<DAO>> onCreateLoader(int id, Bundle args) {
spbProgress.setVisibility(View.VISIBLE);
return new ApiLoader<DAO>(getApplicationContext()) {
#Override
protected DAO callServerInBackground(ApiService api) throws Exception {
return api.requestDAO();
}
};
}
#Override
public void onLoadFinished(Loader<ApiResponse<DAO>> loader, ApiResponse<DAO> data) {
if (!data.hasError()) {
DAO dao = data.getResult();
//handle data
} else {
Exception error = data.getError();
//handle error
}
}
#Override
public void onLoaderReset(Loader<ApiResponse<DAO>> loader) {}
});
If you want to request data multiple times use restartLoader instead of initLoader.
I've been using a kind of MVP (ModelViewPresenter) implementation on my Android apps. For the Retrofit request I made the Activity calls it's respective Presenter, which in turn makes the Retrofit Request and as a parameter I send a Callback with a custom Listener attached to it (implemented by the presenter). When the Callback reach onSuccess or onFailure methods I call the Listener's respective methods, which calls the Presenter and then the Activity methods :P
Now in case the screen is turned, when my Activity is re-created it attaches itself to the Presenter. This is made using a custom implementation of Android's Application, where it keeps the presenters' instance, and using a map for recovering the correct presenter according to the Activity's class.
I don't know if it's the best way, perhaps #pareshgoel answer is better, but it has been working for me.
Examples:
public abstract interface RequestListener<T> {
void onSuccess(T response);
void onFailure(RetrofitError error);
}
...
public class RequestCallback<T> implements Callback<T> {
protected RequestListener<T> listener;
public RequestCallback(RequestListener<T> listener){
this.listener = listener;
}
#Override
public void failure(RetrofitError arg0){
this.listener.onFailure(arg0);
}
#Override
public void success(T arg0, Response arg1){
this.listener.onSuccess(arg0);
}
}
Implement the listener somewhere on the presenter, and on the overrode methods call a presenter's method that will make the call to the Activity. And call wherever you want on the presenter to init everything :P
Request rsqt = restAdapter.create(Request.class);
rsqt.get(new RequestCallback<YourExpectedObject>(listener));
Firstly, your activity leaks here because this line:
api.getUserName(userId, new Callback {...})
creates an anonymous Callback class that holds a strong reference to you MainActivity. When the device is rotated before the Callback is called, then the MainActivity will not be garbage collected. Depending on what you do in the Callback.call(), your app may yield undefined behaviour.
The general idea to handle such scenarios is:
Never create a non-static inner class (or an anonymous class as mentioned in the problem).
Instead create a static class that holds a WeakReference<> to the Activity/Fragment.
The above just prevents Leaks. It still does not help you get the Retrofit call back to your Activity.
Now, to get the results back to your component (Activity in your case) even after configuration change, you may want to use a headless retained fragment attached to your Activity, which makes the call to Retrofit. Read more here about Retained fragment - http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
The general idea is that the Fragment automatically attaches itself to the Activity on configuration change.
I highly recommend you watch this video given at Google I/O.
It talks about how to create REST requests by delegating them to a service (which is almost never killed). When the request is completed it is immediately stored into Android's built-in database so the data is immediately available when your Activity is ready.
With this approach, you never have to worry about the lifecycle of the activity and your requests are handled in a much more decoupled way.
The video doesn't specifically talk about retrofit, but you can easily adapt retrofit for this paradigm.
Use Robospice
All components in your app which require data, register with the spice service. The service takes care of sending your request to the server (via retrofit if you want). When the response comes back, all components which registered get notified. If there is one of them not available any more (like an activity which got kicked because of rotation), it's just not notified.
Benefit: One single request which does not get lost, no matter whether you rotate your device, open new dialogs/fragments etc...
Using Retrofit2 to handle orientation change. I was asked this in a job interview and was rejected for not knowing it at the time but here it is now.
public class TestActivity extends AppCompatActivity {
Call<Object> mCall;
#Override
public void onDestroy() {
super.onDestroy();
if (mCall != null) {
if (mCall.isExecuted()) {
//An attempt will be made to cancel in-flight calls, and
// if the call has not yet been executed it never will be.
mCall.cancel();
}
}
}
}

Verify a static method was called by another static method in PowerMock

I have a Tool class with two static methods, doSomething(Object) and callDoSomething(). The names are intuitive in that callDoSomething delegates its call to doSomething(Object);
public class Tool
{
public static void doSomething( Object o )
{
}
public static void callDoSomething()
{
doSomething( new Object());
}
}
I have a Test class for Tool and I'd like to verify if doSomething(Object) was called (I want to do Argument Matching too in the future)
#RunWith( PowerMockRunner.class )
#PrepareForTest( { Tool.class } )
public class ToolTest
{
#Test
public void toolTest()
{
PowerMockito.mockStatic( Tool.class );
Tool.callDoSomething();// error!!
//Tool.doSomething();// this works! it gets verified!
PowerMockito.verifyStatic();
Tool.doSomething( Mockito.argThat( new MyArgMatcher() ) );
}
class MyArgMatcher extends ArgumentMatcher<Object>
{
#Override
public boolean matches( Object argument )
{
return true;
}
}
}
Verify picks up doSomething(Object) if it's called directly. I've commented this code out above. Verify does NOT pick up doSomething(Object) when using callDoSomething, (this is the code shown above). This is my error log when running the code above:
Wanted but not invoked tool.doSomething(null);
However, there were other interactions with this mock.
at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:260)
at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:192)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:60)
at Tool.doSomething(Tool.java)
at ToolTest.toolTest(ToolTest.java:22)
... [truncated]
I'd like to avoid making any changes to the Tool class. My question is, how can I verify doSomething(Object) was called from callDoSomething(), as well as perform some argument matching on doSomething's param
It sounds like you want to use a static spy (partial mock). The section of the PowerMock documentation that talks about mocking static has a note in the second bullet that could be easily missed:
(use PowerMockito.spy(class) to mock a specific method)
Note, in your example you're not actually mocking the behavior, just verifying the method is called. There's a subtle but important difference. If you don't want doSomething(Object) to be called you'd need to do something like this:
#Test
public void toolTest() {
PowerMockito.spy(Tool.class); //This will call real methods by default.
//This will suppress the method call.
PowerMockito.doNothing().when(Tool.class);
Tool.doSomething(Mockito.argThat( new MyArgMatcher() ));
Tool.callDoSomething();
//The rest isn't needed since you're already mocking the behavior
//but you can still leave it in if you'd like.
PowerMockito.verifyStatic();
Tool.doSomething(Mockito.argThat( new MyArgMatcher() ));
}
If you still want the method to fire though, just remove the two lines for doNothing(). (I added a simple System.out.println("do something " + o); to my version of Tool.java as an additional verification of doNothing().)
You can do your validation with this:
public class Tool{
public static boolean isFromCallDoSomethingMethod= false;
public static void doSomething(Object o){
}
public static void callDoSomething() {
doSomething(new Object());
isFromCallDoSomethingMethod= true;
}
}
You can do the verification as:
if(Tool.isFromCallDoSomethingMethod){
//you called doSomething() from callDoSomething();
}
REMEMBER
Don't forget to do the validation if you call the doSomething() from another way that is not from callDoSomething(), you can do this by ussing Tool.isFromCallDoSomethingMethod = false
Is this what you want?

Categories

Resources