问题
I have the following method I created it's nothing fancy just retrieves data from an HTTP server but it is an async method.
public async Task<string> GetStringFromConsul(string key)
{
string s = "";
// attempts to get a string from Consul
try
{
//async method to get the response
HttpResponseMessage response = await this.http.GetAsync(apiPrefix + key);
//if it responds successfully
if (response.IsSuccessStatusCode)
{
//parse out a string and decode said string
s = await response.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject<List<consulValue>>(s);
s = Encoding.UTF8.GetString(Convert.FromBase64String(obj[0].value));
}
else
{
s = requestErrorCodePrefix + response.StatusCode + ">";
}
}
catch(Exception e)
{
//need to do something with the exception
s = requestExceptionPrefix + e.ToString() + ">";
}
return s;
}
Then in the test I call the code just like I do during normal execution:
[Test]
public async Task GetStringFromConsulTest()
{
ConsulConfiguration cc = new ConsulConfiguration();
string a = cc.GetStringFromConsul("").GetAwaiter().GetResult();
Assert.AreEqual(a, "");
}
However I get an exception like so instead of any sort of string:
Message: Expected string length 514 but was 0. Strings differ at index 0.
Expected: "<Request Exception: System.Threading.Tasks.TaskCanceledExcept..."
But was: <string.Empty>
I've looked around and found a few tutorials on this and tried it but to no avail. If anyone can point me in the right direction I would appreciate it, I'm pretty new to C# unit testing.
回答1:
I'm a stickler for good error messages so I'd first change the assert to
Assert.AreEqual("", a);
because the first argument is your expected value. Now it will fail with
Message: Expected string length 0 but was 514. Strings differ at index 0.
Expected: <string.Empty>
But was: "<Request Exception: System.Threading.Tasks.TaskCanceledExcept..."
...still a failure, but a much more sensible message.
Next, to pass, add an await to your async method call, as suggested by M Hassan.
回答2:
In Nunit Framework, Use async/await in unit test as in the following:
[Test]
public async Task GetStringFromConsulTest()
{
ConsulConfiguration cc = new ConsulConfiguration();
//string a = cc.GetStringFromConsul("").GetAwaiter().GetResult();
//use await instead
string a = await cc.GetStringFromConsul("");
Assert.AreEqual(a, "");
}
For more details, read Async Support in NUnit
It's better to test your method in case of firing exceptions NUnit expected exceptions
Update:
The comment:
I still get the error even when structuring the method like this.
That error means that the test fail and there is a bug in the source code method GetStringFromConsul
.
Your test method include the Assert statement:
Assert.AreEqual(a, "");
That means that you expect a
variable which is calculated from a=cc.GetStringFromConsul("")
should be "" to pass,
otherwise the test fail and NUnit Framework Fire an exception like:
Message: Expected string length 514 but was 0. Strings differ at index 0.
Expected: "<Request Exception: System.Threading.Tasks.TaskCanceledExcept..."
But was: <string.Empty>
To resolve this exception, you should resolve the bug in the method GetStringFromConsul
to return "" when the input parameter=""
回答3:
Maybe this.http.GetAsync(apiPrefix + key);
is timing out. That would give you a TaskCanceledException. Not sure what your value of apiPrefix is.
来源:https://stackoverflow.com/questions/49338398/async-unit-testing-with-nunit-and-c-sharp