Rhino Mock Stub Async Method - unit-testing

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.

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.

AWS Lambda - Asynchronously invoked function but nothing happens

I have 2 lambda functions, my first function w/c we'll call "PostStep" invokes another lambda function "RetryStep" asynchronously whenever a timeout occurs. It's been working fine ever since. Now I have to do some code changes, and during testing, a weird issue occurred.
Upon timeout, it still calls the RetryStep function asynchronously, but then the function is not really being invoked. I tried invoking the PostStep function again, then I noticed that's the time when the RetryStep function is really invoked, but with the previous request's data.
Here's how I'm doing the invocation:
LivePostingService.class
#Override
public void postTransaction(Transaction transaction) {
... some posting logic ...
conditionalCallRetryLambdaFunction(transaction);
}
private void conditionalCallRetryLambdaFunction(Transaction transaction) {
try {
String payload = objectMapper.writeValueAsString(transaction);
lambdaInvokerService.invokeAsync(lambdaRetryFunctionName, payload);
} catch (JsonProcessingException e) {
if(LOGGER.isErrorEnabled()) {
LOGGER.error(e.getMessage(), e);
}
}
}
LambdaInvokerService.class
#Service
public class LambdaInvokerServiceImpl implements LambdaInvokerService {
LOGGER.info("Calling lambda function: " + functionName + ", with payload: " + payload);
InvokeRequest req = new InvokeRequest()
.withFunctionName(functionName)
.withInvocationType(InvocationType.Event)
.withPayload(payload);
AsyncHandler<InvokeRequest, InvokeResult> asyncHandler = new AsyncHandler<InvokeRequest, InvokeResult>() {
#Override
public void onError(Exception e) {
LOGGER.error(e.getMessage());
}
#Override
public void onSuccess(InvokeRequest request, InvokeResult invokeResult) {
LOGGER.info("Success! " + invokeResult);
}
};
lambdaAsyncClient.invokeAsync(req, asyncHandler);
}
Here's my handler:
#Override
public Void handleRequest(DynamodbEvent dynamodbEvent, Context context) {
livePostingService.postTransaction(transaction);
return null;
}
As you can see from the code, the log Calling lambda function.. appears at the end of PostStep function, but the log Success! appears at the beginning of the PostStep function if i invoke it again.
It's the same code with what's currently on our production. I even did a git checkout on our master branch then ran it on dev, but the same issue still occurs. Do you have any idea about this?
Thanks!

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!

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.