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

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!

Related

Fake internal calls of a SUT with FakeItEasy

I have a small C# class that handles printing.
I want to create (n)unit tests for this class, using
fakeItEasy. How can I fake the internal calls of this
class without faking the whole SUT ?
For example:
public class MyPrintHandler: IMyPrintHandler
{
public MyPrintHandler(ILogger<MyPrintHandler> logger)
{
}
// function I want to (unit test
public async Task<bool> PrintAsync(string ipaddress)
{
try
{
if (!string.IsNullOrWhiteSpace(ipaddress) )
{
return await StartPrint(ipaddress); // This cannot be called in a unit test, because it really start printing on a printer.
}
}
catch (Exception e)
{
}
return false;
}
private async Task<bool> StartPrint(string ipaddress)
{
// prints on the printer
}
[TestFixture]
public class MyPrintHandlerTests
{
[Test]
public void Succes_PrintAsync()
{
using (var fake = new AutoFake())
{
// Arrange - configure the fake
var sut = fake.Resolve<MyPrintHandler>();
// Act
await sut.PrintAsync("0.0.0.0"); // I want to prevent StartPrint() from being called..
}
}
}
How can I achieve this, or is this not possible at all?
Thanks in advance!
I would typically say that faking the SUT is an anti-pattern, to be avoided whenever possible, as it causes confusion. If you can refactor to introduce a collaborator that handles the StartPrinting method, I would strongly consider doing so. If this is not possible, you can try this, however
any method that you want to fake must be virtual or abstract, otherwise FakeItEasy cannot intercept it
any method that you want to fake must be public (or internal, if you can grant dynamic proxy access to production code's internals)
you would then fake the SUT, specifying that it should call the original (base) methods, and finally
explicitly override the behaviour for the method that you want to intercept

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.

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.

Invoke callback in Moq

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.