Verify that an async method was called using NSubstitute throws exception - c#

When I try to verify that an async method was called using NSubstitute, I get an error message
NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods
Here's some example code to illustrate my point:
public interface ISender
{
Task Send(string message);
}
public class Service
{
private readonly ISender _sender;
public Service(ISender sender)
{
_sender = sender;
}
public async Task SendMessage(List<string> messages)
{
foreach (var message in messages)
{
await _sender.Send(message);
}
}
}
[Test]
public async Task Test_Async_Method()
{
var mock = Substitute.For<ISender>();
var service = new Service(mock);
var messages = new List<string>{"Foo","Bar"};
await service.SendMessage(messages);
mock.Send(Arg.Any<string>()).Received(2);
}
I understand that the problem is that I'm verifying Taskand not mock.Send(Arg.Any<string>()), but what can I do about it?

You should invert the calls:
mock.Received(2).Send(Arg.Any<string>());
Source: http://nsubstitute.github.io/help/received-calls/

Related

HttpClient Extension with Eventhandler

I'm trying to extend the HttpClient with an EventHandler.
Is this possible?
I have an Extension on HttpClient as follows:
public static class HttpClientExtensions
{
public async static Task<T> GetSomthingSpecialAsync<T>(this HttpClient client, string url)
{
using var response = await client.GetAsync(url);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
//I have an error and want to raise the HttpClientEventError
HttpClientErrorEvent(null, new HttpClientErrorEventArgs()
{
StatusCode = response.StatusCode,
Message = $"{response.StatusCode } {(int)response.StatusCode } "
});
return default(T);
}
response.EnsureSuccessStatusCode();
[... ]
}
}
public class HttpClientErrorEventArgs : EventArgs
{
public System.Net.HttpStatusCode StatusCode { get; set; }
public string Message { get; set; }
}
But how do I define the HttpClientErrorEvent?
I tried the following but it is not an extension to a specific HttpClient:
public static event EventHandler<HttpClientErrorEventArgs> HttpClientErrorEvent = delegate { };
Don't use an event to return errors. For starters, how are you going to identify which request raised which error? You'd have to register and unregister event handlers around each call but how would you handle concurrent calls? How would you compose multiple such calls?
Errors aren't events anyway. At best, you'd have to handle the event as if it was a callback - in which case why not use an actual callback?
public async static Task<T> GetSomethingSpecialAsync<T>(this HttpClient client, string url,Action<(HttpStatusCode Status,string Message)> onError)
{
...
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
onError(response.Status,....);
return default;
}
}
...
var value=await client.GetSomethingSpesialAsync(url,
(status,msg)=>{Console.WriteLine($"Calling {url} Failed with {status}:{msg}");}
);
async/await was created so people can get rid of callbacks and events though. It's almost impossible to compose multiple async calls with events, and hard enough to do so with callbacks. That's why a lot of languages (C#, JavaScript, Dart, even C++ in a way ) introduced promises and async/await to get rid of both the success and error callback.
Instead of calling a callback you can actually return either a result or an error from your function. This is a functional way embedded in eg F#, Rust and Go (through tuples). There are a lot of ways to do this in C#:
Return a tuple with the value and error, eg (T? value, string? error)
Create a record with the value and error
Create separate Success and Error classes that share a common IResult<T> interface
Pattern matching can be used with any option to retrieve either the error or value without a ton of if statements.
Let's say we have a specific error type, HttpError.:
record HttpError(HttpStatusCode Status,string Message);
Using tuples, the method becomes:
public async static Task<(T value,HttpError error> GetSomethingSpecialAsync<T>(this HttpClient client,string url)
{
...
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
return (default,new HttpError(response.Status,....);
}
}
And called :
var (value,error)=await client.GetSomethingSpecialAsync(url);
if(error!=null)
{
var (status,msg)=error;
Console.WriteLine($"Calling {url} Failed with {status}:{msg}");
...
}
Instead of a tuple, we can create a Result record:
record Result<T>(T? Value,HttpError? Error);
Or separate classes:
interface IResult<T>
{
bool IsSuccess{get;}
}
record Success<T>(T Value):IResult<T>
{
public bool IsSuccess=>true;
}
record Error<T>(HttpError Error):IResult<T>
{
public bool IsSuccess => false;
}
public async static Task<IResult<T>> GetSomethingSpecialAsync<T>(this HttpClient client,string url){...}
var result=await client.GetSomethingSpecialAsync(url);
In all cases pattern matching can be used to simplify handling the result, eg:
var result=await client.GetSomethingSpecialAsync<T>(url);
switch (result)
{
case Error<T> (status,message):
Console.WriteLine($"Calling {url} Failed with {Status}:{Message}");
break;
case Success<T> (value):
...
break;
}
Having a specific Result<T> or IResult<T> type makes it easy to write generic methods to handle success, errors or compose a chain of functions. For example, the following could be used to call the "next" function if the previous one succeeded, otherwise just propagate the "error" :
IResult<T> ThenIfOk(this IResult<T> previous,Func<T,IResult<T>> func)
{
return previous switch
{
Error<T> error=>error,
Success<T> ok=>func(ok.Value)
}
}
This would allow creating a pipeline of calls :
var finalResult=doSomething(url)
.ThenIfOk(value=>somethingElse(value))
.ThenIfOk(....);
This style is called Railway oriented programming and is very common in functional and dataflow (pipeline) programming
You could store the handlers in your extension class and do something like this ? Please note this code is not thread safe and need to be synchronized around dictionary and list access !
public static class HttpClientExtensions
{
private static Dictionary<HttpClient, List<Action<HttpClientErrorEventArgs>>> Handlers { get; set; }
static HttpClientExtensions()
{
Handlers = new Dictionary<HttpClient, List<Action<HttpClientErrorEventArgs>>>();
}
public async static Task<T> GetSomthingSpecialAsync<T>(this HttpClient client, string url)
{
////code ....
//I have an error and want to raise the HttpClientEventError
HttpClientErrorEventArgs args = null;
client.RaiseEvent(args);
return default(T);
////code
}
public static void AddHandler(this HttpClient client, Action<HttpClientErrorEventArgs> handler)
{
var found = Handlers.TryGetValue(client, out var handlers);
if (!found)
{
handlers = new List<Action<HttpClientErrorEventArgs>>();
Handlers[client] = handlers;
}
handlers.Add(handler);
}
public static void RemoveHandler(this HttpClient client, Action<HttpClientErrorEventArgs> handler)
{
var found = Handlers.TryGetValue(client, out var handlers);
if (found)
{
handlers.Remove(handler);
if (handlers.Count == 0)
{
Handlers.Remove(client);
}
}
}
private static void RaiseEvent(this HttpClient client, HttpClientErrorEventArgs args)
{
var found = Handlers.TryGetValue(client, out var handlers);
if (found)
{
foreach (var handler in handlers)
{
handler.Invoke(args);
}
}
}
}

How to show warning for a method if it is called directly in c#

{
public class MyClass
{
// all the call to GetData() of apiHelper should pass through this method
public async Task<T> InitiateAPICallAsync<T>(Task<T> apiCall) where T : BaseResponse
{
var response = await apiCall;
// some common code work using response data
return response;
}
public async void MyFunc()
{
var helper = new APIHelper("1", "2");
//
var response1 = await InitiateAPICallAsync(helper.GetData<Response1>()); // correct way
var rewponse2 = await helper.GetData<Response1>(); // incorrect way, need to show warning
}
}
public class APIHelper
{
public APIHelper(string a, string b)
{
// some code
}
public async Task<T> GetData<T>()
{
await Task.Delay(1000); // network call
// other code
return default;
}
}
public class Response1 : BaseResponse { }
public class Response2 : BaseResponse { }
public class BaseResponse { }
}
in my application MyClass, there is a method named InitiateAPICallAsync(). All call to the GetData() method of APIHelper must be pass through this method. I need to showing warning, if GetAsync() method called directly without passing through InitiateAPICallAsync.
Note: It is a sample code snippet, where in my real time project the APIHelper represents a Connectivity library. and MyClass represents another library named service.
How to show warning for a method if it is called directly in c#
Using CallerMemberName attribute is core thread of the following solution, thanks for Fumeaux's comment, I tried place CallerMemberName attribute above GetData method directly to get the caller, but the result is MyFunc but not InitiateAPICallAsync. So I tried use delegate as the InitiateAPICallAsync parameter that could make sure GetData will called by InitiateAPICallAsync. The following code has been simplified.
public delegate Task<int> PrintCaller([CallerMemberName] string Caller = null);
public class MyClass
{
public async Task<string> InitiateAPICallAsync(PrintCaller apiCall)
{
var response = await apiCall();
return "Test";
}
public async void MyFunc()
{
var helper = new APIHelper();
var str1 = await InitiateAPICallAsync(new PrintCaller(helper.GetData));
var str2 = await helper.GetData();
}
}
public class APIHelper
{
public async Task<int> GetData([CallerMemberName] string Caller = null)
{
if (Caller == "InitiateAPICallAsync")
{
// do some thing
}
else
{
//Show Warning
var dialog = new MessageDialog("Waring!!! Please don't call it directly");
await dialog.ShowAsync();
}
return 0;
}
}

Cannot unit test a class with a method returning RedisResult with StackExchange.Redis

I have a simple wrapper for stackexchange redis:
public interface IRedisClient
{
Task<RedisResult> ScriptEvaluate(LuaScript script, object parameters);
}
I have a method that calls ScriptEvaluate
public class Foo
{
private readonly IRedisClient _client;
public Foo(IRedisClient client)
{
_client = client;
}
public void RunScript()
{
_client.ScriptEvaluate(LuaScript.Prepare(""), new object());
}
}
Now when I use NSubstitute to mock IRedisClient that is injected to Foo and then call RunScript
public void Test()
{
_foo = new Foo(Substitute.For<IRedisClient>());
_foo.RunScript();
}
I get the following error:
System.TypeLoadException: Method 'AsBoolean' in type
'Castle.Proxies.RedisResultProxy' from assembly
'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=a621a9e7e5c32e69' does not have an implementation.
As far as I can see Nsubstitute/Castle internals do not manage to work with RedisResult properly. I did not manage to find out any workarounds.
Is it possible to do something with this?
P.S. I get the same error when I try to configure the mock to return a value (same exception):
_client
.ScriptEvaluate(null, null)
.ReturnsForAnyArgs(RedisResult.Create((RedisKey)"result"));
I was curious about why mocking the abstract RedisResult was not a simple solution.
This appears to be an issue with NSubstitute's implementation.
Using the following to try and recreate the problem
public class Foo {
private readonly IRedisClient _client;
public Foo(IRedisClient client) {
_client = client;
}
public Task<RedisResult> RunScript() {
return _client.ScriptEvaluate(LuaScript.Prepare(""), new object());
}
}
I was able to reproduce it using NSubstitute but was able to exercise the test to completion when using another mocking framework (MOQ)
[TestClass]
public class MyTestClass {
[TestMethod]
public async Task Test1() {
//Arrange
var expected = RedisResult.Create((RedisKey)"result");
var _client = Substitute.For<IRedisClient>();
_client
.ScriptEvaluate(Arg.Any<LuaScript>(), Arg.Any<object>())
.Returns(expected);
var _foo = new Foo(_client);
//Act
var actual = await _foo.RunScript();
//Assert
actual.Should().Be(expected);
}
[TestMethod]
public async Task Test2() {
//Arrange
var expected = RedisResult.Create((RedisKey)"result");
var _client = Mock.Of<IRedisClient>(_ => _.ScriptEvaluate(It.IsAny<LuaScript>(), It.IsAny<object>()) == Task.FromResult(expected));
var _foo = new Foo(_client);
//Act
var actual = await _foo.RunScript();
//Assert
actual.Should().Be(expected);
}
}
RedisResult is an abstract type, but there are static Create methods for common scenarios, and a few static properties such as EmptyArray, NullArray, etc. I can't tell you how to configure your particular faking layer, but ultimately, I'd expect something involving RedisResult.Create

Testing property set by async method

I try to test a class with NUnit that contains async methods. I don't know how to do it in a correct way.
I have a class with that looks like this:
public class EditorViewModel:INotifyPropertyChanged
{
public void SetIdentifier(string identifier)
{
CalcContentAsync();
}
private async void CalcContentAsync()
{
await SetContentAsync();
DoSomething();
}
private async Task SetContentAsync()
{
Content = await Task.Run<object>(() => CalculateContent());
RaisePropertyChanged("Content");
}
public object Content { get; private set; }
...
}
How can I write a Test in NUnit, that checks, that the Content-Property is set to the right value? I want to do something like that:
[Test]
public void Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}
But that doesn't work. Because the asynchronous code has not been executed before the assertion.
Your SetIdentifier method is async too (or you need to make it async because you wait operation inside it. Then your method can looks like next one:
public async Task SetIdentifier(string identifier)
{
await SetContentAsync();
DoSomething();
}
And now you can just await it in your unit test:
[Test]
public async Task Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
await viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}
You can also use workaround to call your test in a sync manner:
[Test]
public async Task Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
Task.Run(async () =>
{
var viewModel = new EditorViewModel();
await viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}).GetAwaiter().GetResult();
}
Via MSDN Magazine.
When working with async you should always return a Task. Otherwise it would be "fire and forget", and you have absolutely no way of interacting with the Task.
Therefore you should change the signature of SetIdentifier to return a Task, like this:
public async Task SetIdentifier(string identifier)
{
await SetContentAsync();
DoSomething();
}
Then you can wait for the operation to complete in the test:
[Test]
public async void Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
await viewModel.SetIdentifier("XXX");
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}
Or, if your test runner does not support async:
[Test]
public void Content_WhenModifierIsXXX_ReturnsSomeViewModel()
{
var viewModel = new EditorViewModel();
viewModel.SetIdentifier("XXX").Wait();
Assert.That(viewModel.Content, Is.InstanceOf<ISomeContentViewModel>());
}

Making interface implementations async

I’m currently trying to make my application using some Async methods.
All my IO is done through explicit implementations of an interface and I am a bit confused about how to make the operations async.
As I see things I have two options in the implementation:
interface IIO
{
void DoOperation();
}
OPTION1:
Do an implicit implementation async and await the result in the implicit implementation.
class IOImplementation : IIO
{
async void DoOperation()
{
await Task.Factory.StartNew(() =>
{
//WRITING A FILE OR SOME SUCH THINGAMAGIG
});
}
#region IIO Members
void IIO.DoOperation()
{
DoOperation();
}
#endregion
}
OPTION2:
Do the explicit implementation async and await the task from the implicit implementation.
class IOAsyncImplementation : IIO
{
private Task DoOperationAsync()
{
return new Task(() =>
{
//DO ALL THE HEAVY LIFTING!!!
});
}
#region IIOAsync Members
async void IIO.DoOperation()
{
await DoOperationAsync();
}
#endregion
}
Are one of these implementations better than the other or is there another way to go that I am not thinking of?
Neither of these options is correct. You're trying to implement a synchronous interface asynchronously. Don't do that. The problem is that when DoOperation() returns, the operation won't be complete yet. Worse, if an exception happens during the operation (which is very common with IO operations), the user won't have a chance to deal with that exception.
What you need to do is to modify the interface, so that it is asynchronous:
interface IIO
{
Task DoOperationAsync(); // note: no async here
}
class IOImplementation : IIO
{
public async Task DoOperationAsync()
{
// perform the operation here
}
}
This way, the user will see that the operation is async and they will be able to await it. This also pretty much forces the users of your code to switch to async, but that's unavoidable.
Also, I assume using StartNew() in your implementation is just an example, you shouldn't need that to implement asynchronous IO. (And new Task() is even worse, that won't even work, because you don't Start() the Task.)
Better solution is to introduce another interface for async operations. New interface must inherit from original interface.
Example:
interface IIO
{
void DoOperation();
}
interface IIOAsync : IIO
{
Task DoOperationAsync();
}
class ClsAsync : IIOAsync
{
public void DoOperation()
{
DoOperationAsync().GetAwaiter().GetResult();
}
public async Task DoOperationAsync()
{
//just an async code demo
await Task.Delay(1000);
}
}
class Program
{
static void Main(string[] args)
{
IIOAsync asAsync = new ClsAsync();
IIO asSync = asAsync;
Console.WriteLine(DateTime.Now.Second);
asAsync.DoOperation();
Console.WriteLine("After call to sync func using Async iface: {0}",
DateTime.Now.Second);
asAsync.DoOperationAsync().GetAwaiter().GetResult();
Console.WriteLine("After call to async func using Async iface: {0}",
DateTime.Now.Second);
asSync.DoOperation();
Console.WriteLine("After call to sync func using Sync iface: {0}",
DateTime.Now.Second);
Console.ReadKey(true);
}
}
P.S.
Redesign your async operations so they return Task instead of void, unless you really must return void.
I created a sample app based on Svick's answer and found that calling IOImplementation.DoOperationAsync() without the async keyword does not result in a compiler/Visual Studio warning. This was based on Visual Studio 2019 and .NET Core 3.1.
Sample code below.
public interface ISomething
{
Task DoSomethingAsync();
}
public class Something : ISomething
{
public async Task DoSomethingAsync()
{
await Task.Run(() => Thread.Sleep(2000));
Console.WriteLine("Message from DoSomethingAsync");
throw new Exception("Some exception");
}
}
class Program
{
static void Main(string[] args)
{
ISomething something = new Something();
Console.WriteLine("pre something.DoSomethingAsync() without await");
something.DoSomethingAsync(); // No compiler warning for missing "await" and exception is "swallowed"
Console.WriteLine("post something.DoSomethingAsync() without await");
Thread.Sleep(3000);
// Output:
// pre something.DoSomethingAsync() without await
// post something.DoSomethingAsync() without await
// Message from DoSomethingAsync
}
}
An abstract class can be used instead of an interface (in C# 7.3).
// Like interface
abstract class IIO
{
public virtual async Task<string> DoOperation(string Name)
{
throw new NotImplementedException(); // throwing exception
// return await Task.Run(() => { return ""; }); // or empty do
}
}
// Implementation
class IOImplementation : IIO
{
public override async Task<string> DoOperation(string Name)
{
return await await Task.Run(() =>
{
if(Name == "Spiderman")
return "ok";
return "cancel";
});
}
}

Categories