Invoke callback in Moq - unit-testing

I have a method that performs an asynchronous service call. I call this class by passing in the callback.
public void GetRights(EventHandler<GetRightsCompletedEventArgs> callback)
{
ServiceClient client = new ServiceClient();
client.GetRightsCompleted += new EventHandler<GetRightsCompletedEventArgs>(callback);
client.GetRightsAsync();
}
GetRights(GetRightsCallback);
I'm creating tests with MSTest, and I've mocked the containing class (IGetRightsProxy) in Moq. How can I invoke the callback when this method is called in the test?
GetRightsForCurrentUserCompletedEventArgs results =
new GetRightsCompletedEventArgs(
new object[] { new ObservableCollection<Right>()}, null, false, null);
Mock<IGetRightsProxy> MockIGetRightsProxy = new Mock<GetRightsProxy>();

One way of doing what I want is to extend the class like this:
class MockGetRightsProxy : IGetRightsProxy
{
public void GetRights(EventHandler<GetRightsCompletedEventArgs> callback)
{
// Create some args here
GetRightsCompletedEventArgs args = new GetRightsCompletedEventArgs(
new object[] { new ObservableCollection<Right>() }, null, false, null);
callback(null, args);
}
}
I was looking for ways to invoke the callback in Moq, but this works, too.

You want to be looking at Moq's Callback() extension on your mock;
Mock<IGetRightsProxy> mock = new Mock<IGetRightsProxy>();
mock.Setup(x => x.GetRights(It.IsAny<EventHandler<GetRightsCompletedEventArgs>>())
.Callback<EventHandler<GetRightsCompletedEventArgs>>(
callback => callback(mock.Object, new GetRightsCompletedEventArgs())
);
When the code under test calls GetRights() on the IGetRightsProxy mock the actual EventHandler<GetRightsCompletedEventArgs> it passes in will subsequently be passed into Moq's Callback() method.
Note: Type inference will work on the generic applied to Callback() but I find in these cases it is a bit more readable to explicitly define the type being passed into the method.

Related

How would one unit test api call method (rxjava+retrofit)?

I'm trying to unit test an api call made with retrofit and rxjava.
In order to do that i'm mocking the api call object but api calls subscriber won't trigger its onNext method.
ApiCallsTest.java:
//custom object replacing api call response object
Observable<FastRechargeClass[]> apiObservable = Observable.just(fastRechargeList);
InterfaceAPI api = mock(InterfaceAPI.class);
when(retrofitApi.getApiInterface(context)).thenReturn(api); when(api.getLatestTransactions("token")).thenReturn(apiObservable);
apiCalls.getLatestTransactions("token",context);
ApiCalls.java:
public void getLatestTransactions(String token, final Context context) {
String methodName = "getLatestTransactions";
InterfaceAPI api = retrofitApi.getApiInterface(context);
Observable<FastRechargeClass[]> call = api.getLatestTransactions(token);
call.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new Observer<FastRechargeClass[]>() {
#Override
public void onSubscribe(Disposable d) {
WriteLog.print("onSubscribe");
}
#Override
public void onNext(FastRechargeClass[] fastRechargeClasses) {
fastRechargeManager.runUpdateFastRechargeDb(fastRechargeClasses);
}
#Override
public void onError(Throwable e) {
logOnFailureRequests(methodName, e.getMessage());
}
#Override
public void onComplete() {
}
});
}
When running test
onSubscribe is being called and it stops
You need to trigger event emission manually. To do this you need to call method
.blockingFirst()
or
.blockingGet()
depends of observable type you are using.
So you have to add
call.blockingGet()
at the end of getLatestTransactions method or this method should return created observable and call blocking get inside a test method.

Use Mockito to unit test a function which calls async function

I have a method which calls async function:
public class MyService {
...
public void uploadData() {
MyPool.getInstance().getThreadPool().execute(new Runnable() {
#Override
public void run() {
boolean suc = upload();
}
});
}
}
I want to unit test this function with Mockito, I tried:
MyPool mockMyPool = Mockito.mock(MyPool.class);
ThreadPool mockThreadPool = Mockito.mock(ThreadPool.class);
ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
when(mockMyPool.getThreadPool()).thenReturn(mockThreadPool);
MyService service = new MyService();
// run the method under test
service.uploadData();
// set the runnableCaptor to hold your callback
verify(mockThreadPool).execute(runnableCaptor.capture());
But I got error:
org.mockito.exceptions.verification.WantedButNotInvoked:
Wanted but not invoked:
threadPool.execute(
<Capturing argument>
);
Why I got this error, how to unit test uploadData() function with Mockito?
OK, I figured out a way by myself, since MyPool is an singleton. I added one public function setInstance(mockedInstance) to pass the mocked instance to MyPool. Then, it works. I know it is a bit "dirty", but if you have better solution, please let me know. Thanks!
Aside from the DI approach you found of keeping a MyPool or ThreadPool field, you can also refactor a little bit to allow for dependency injection in your method:
public class MyService {
...
public void uploadData() {
uploadData(MyPool.getInstance().getThreadPool());
}
/** Receives an Executor for execution. Package-private for testing. */
void uploadData(Executor executor) {
executor.execute(new Runnable() {
#Override public void run() {
boolean suc = upload();
}
});
}
}
This might be even cleaner, because it reduces your ThreadPool to the level of abstraction you need (Executor), which means you're only mocking a one-method interface rather than your ThreadPool (which I assume is related to ThreadPoolService; otherwise, you can just accept a ThreadPool, too). Officially your uploadData() would be untested, but you could easily and thoroughly test uploadData(Executor) or uploadData(ThreadPool), which are the moving parts most likely to break.
The package-private trick does rely on your code and tests to be in the same package, though they could be in different source folders; alternatively, you could just make the ThreadPool-receiving call a part of your public API, which would allow for more flexibility later.

How to mock the parameter in an anonymous callback by using mockito?

I want to unit test my code below with Mockito, could anyone let me know how I can mock the response from the callback, which is anonymous in my code? Particularly, how can I verify if doSomethingOnResponse() gets called with the mocked response?
public void runTask() {
Data data = null;
ClassA objA = new ClassA(new Callback() {
#Override
public void onResponse(Response response) {
data = getSomethingFromResponse(response);
}
};
//this is a synchronous call
objA.run();
doSomethingElse(data); //data gets assigned from the callback
}
Thanks a lot in advance!

Rhino Mock Stub Async Method

I have a ViewModel which, in the constructor, makes a call to an async void method to add to a collection
public MyViewModel(ICommandHandler commandHandler)
{
_commandHandler = commandHandler;
SetupCollection();
}
private async void SetupCollection()
{
var commands = GetCommands();
foreach (var command in commands)
{
var response = await _commandHandler.ExecuteGetReply(command);
if (response != null)
Response.Add(response);
}
}
How exactly would I stub the _commandHandler.ExecuteGetReply() command to return a value?
Also, is it OK to have such a function in the constructor to do something like this? Or should this perhaps go within an... override void OnActivate() call (I'm using Caliburn Micro) ?
ICommandHandler.ExecuteGetReply appears to return a Task<Response> so you can do something like:
ICommand commandArg;
Response response;
stubHandler.Stub(h => h.ExecuteGetReply(commandArg)).Return(Task.FromResult(response));
I wouldn't call an async void method from your constructor however, since you will have no way of being notified when it has completed.

How to verify event subscribed using Moq

I am using MVVM pattern and silverlight 4.0 and Moq for testing.
In the view model constructor, am passing an IEventAggregator object. This object is used to subscribe to an event called SelectionChangedEvent.
In the test method I am doing like this:
this.selectedEvent = new Mock<SelectionChangedEvent>();
this.eventAggregator.Setup(x => x.GetEvent<SelectionChangedEvent>()).Returns(this.selectedEvent.Object);
var viewModel = new ViewModel(this.eventAggregator);
I want to test that the event is getting subscribed when the constructor is called.
How can I verify this?
[Disclaimer: I haven't been able to test this under Silverlight]
Here's a possible solution that basically executes a callback to set an external boolean when Subscribe is called on the event. See comments below though.
[Test]
public void Constructor_CallsSubscribeOnSelectionChangeEvent()
{
var subscribeCalled = false;
var selectedEvent = new Mock<SelectionChangedEvent>();
var eventAggregator = new Mock<IEventAggregator>();
selectedEvent
.Setup(x => x.Subscribe(
It.IsAny<Action<object>>(),
It.IsAny<ThreadOption>(),
It.IsAny<bool>(),
It.IsAny<Predicate<object>>()))
.Callback<Action<object>, ThreadOption, bool, Predicate<object>>
((action, option, f, pred) => { subscribeCalled = true; });
eventAggregator
.Setup(x => x.GetEvent<SelectionChangedEvent>()).Returns(selectedEvent.Object);
var viewModel = new ViewModel(eventAggregator.Object);
Assert.That(subscribeCalled, Is.EqualTo(true));
}
The above is pretty ugly, mostly due to the fact the the only mockable (virtual) overload of the Event's Subscribe method takes four arguments and that the argument types of Callback() can't be deduced automatically - which leads to lots of "extraneous" code.
An alternative would be to instead mock EventBase.InternalSubscribe, which only takes a single argument; but as that method is protected this approach has its own caveats.