Async unit testing with NUnit and C#

江枫思渺然 提交于 2020-12-13 03:58:02

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!