{"id":1289,"date":"2010-11-04T21:36:25","date_gmt":"2010-11-04T20:36:25","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=1289"},"modified":"2021-11-22T07:34:05","modified_gmt":"2021-11-22T06:34:05","slug":"c-5-0-async-feature-unit-testing-part-i","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2010\/11\/c-5-0-async-feature-unit-testing-part-i\/","title":{"rendered":"C# 5.0 Async-Feature: Unit Testing, Part I"},"content":{"rendered":"<div id=\"attachment_1306\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/csharp-goes-async.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1306\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/csharp-goes-async-300x213.png\" alt=\"CSharp goes async\" title=\"csharp-goes-async\" class=\"size-medium wp-image-1306\" width=\"300\" height=\"213\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/csharp-goes-async-300x213.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/csharp-goes-async.png 900w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1306\" class=\"wp-caption-text\">CSharp goes async<\/p><\/div>\n<p><span style=\"color: #ff0000; font-size: medium;\">Disclaimer: <\/span><span style=\"font-size: medium;\">This post is based on the C# 5.0 CTP. Everything described here is subject to future changes. <\/span><\/p>\n<p>I\u2019ve already discussed some implications of the async feature in my <a href=\"?p=1263\">previous post<\/a>.&nbsp; In this post I focus on some challenges for unit test. Once again I assume that everyone is informed about the basics of the new feature. Otherwise I recommend to visit the <a href=\"http:\/\/msdn.microsoft.com\/en-gb\/vstudio\/async.aspx\">official CTP-site<\/a> which links to videos, blog-posts, white-papers and the binaries to try it yourself.<\/p>\n<p>Let\u2019s examine how the async-stuff affects unit testing. Suppose we write a small desktop application which does some work in the background. We\u2019re going write some tests for it.&nbsp; First lets start with a simple, classic test without any async operations.<\/p>\n<p>The Test <script src=\"https:\/\/gist.github.com\/661599.js?file=MyBusinessLogicTest-1.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">[Test]\npublic void ExpectTonsOfMoney(){\n    var toTest = new MyBusinessLogic();\n    var result = toTest.AwesomeBusinessOperation();\n    Assert.AreEqual(&quot;Tons of money&quot;,result);\n}<\/code><\/pre><\/noscript><\/p>\n<p>The Implementation <script src=\"https:\/\/gist.github.com\/661599.js?file=MyBusinessLogic-1.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">public string AwesomeBusinessOperation()\n{\n    var firstPart = TakesALongTimeToProcess(&quot;Tons&quot;);\n    var secondPart = TakesALongTimeToProcess(firstPart+&quot; of &quot;);\n    var result = TakesALongTimeToProcess(secondPart+&quot;money&quot;);\n    return result;\n}\n\nprivate string TakesALongTimeToProcess(string word)\n{\n    \/\/ This operation takes a while\n    Thread.Sleep(1000);\n    return word;\n}<\/code><\/pre><\/noscript><\/p>\n<p>Since calculating the string \u2018Tons of money\u2019 takes a long time and leaves our GUI unresponsive we\u2019re going to improve the situation. We\u2019re taking advantage of the new async support. Since this tiny example doesn\u2019t have any real asynchronous operations we just spin off a task which sleeps of a while. In real application you would call other async API\u2019s which do the work. Then we refactor the method \u2018AwesomeBusinessOperation\u2019 to return a Task of string and use the await operator in the sub-operation.&nbsp; We also add the suffix \u2018Async\u2019 to the methods to distinguish them from regular operations. <script src=\"https:\/\/gist.github.com\/661599.js?file=MyBusinessLogic-2.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">public async Task&lt;string&gt; AwesomeBusinessOperationAsync()\n{\n    var firstPart = await TakesALongTimeToProcessAsync(&quot;Tons&quot;);\n    var secondPart = await TakesALongTimeToProcessAsync(firstPart + &quot; to &quot;);\n    var result = await TakesALongTimeToProcessAsync(secondPart + &quot;money&quot;);\n    return result;\n}\n\nprivate Task&lt;string&gt; TakesALongTimeToProcessAsync(string word)\n{\n    \/\/ Remember, this is just a simulation\n    \/\/ Usually you would use some other async API here\n    return TaskEx.Run(() =&gt;\n                   {\n                       \/\/ This operation takes a while\n                       Thread.Sleep(1000);\n                       return word;\n\n                   });\n}<\/code><\/pre><\/noscript><\/p>\n<p>Now we change the test. Luckily this is very easy. Instead of using the result directly we just use the Task.Result property. This will block the thread until the calculation is done. This also means we\u2019ve no trouble testing it, we just can wait for the result.&nbsp; So we can refactor to async operations without making our tests a nightmare. <script src=\"https:\/\/gist.github.com\/661599.js?file=MyBusinessLogicTest-2.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">[Test]\npublic void ExpectTonsOfMoney(){\n    var toTest = new MyBusinessLogic();\n    var result = toTest.AwesomeBusinessOperationAsync();\n    Assert.AreEqual(&quot;Tons of money&quot;,result.Result);\n}<\/code><\/pre><\/noscript><\/p>\n<h2>Testing Side-Effects<\/h2>\n<p>Now our example about is quite na\u00efve, isn\u2019t it? I mean we just calculated some result, which is easy to test. Let\u2019s look at a example where we have some side effects. A typical example for a desktop application is to trigger events. Again we start with a simple, synchronous example.<\/p>\n<p>The Test <script src=\"https:\/\/gist.github.com\/661651.js?file=MyBusinessLogicTest-1.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">[Test]\npublic void ExpectEventToBeFired(){\n    var toTest = new MyBusinessLogic();\n    var eventFiredExpected = &quot;&quot;;\n    toTest.OperationFinishedNotification \n        += eventArgument =&gt;\n                    {\n                        eventFiredExpected = eventArgument;\n                    };\n    var result = toTest.AwesomeBusinessOperation();\n    Assert.AreEqual(&quot;Tons of money&quot;,eventFiredExpected);\n}<\/code><\/pre><\/noscript><\/p>\n<p>The Implementation  <script src=\"https:\/\/gist.github.com\/661651.js?file=MyBusinessLogic-1.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">public event Action&lt;string&gt; OperationFinishedNotification; \n\npublic string AwesomeBusinessOperation()\n{\n    var firstPart = TakesALongTimeToProcess(&quot;Tons&quot;);\n    var secondPart = TakesALongTimeToProcess(firstPart + &quot; of &quot;);\n    var result = TakesALongTimeToProcess(secondPart + &quot;money&quot;);\n\n    var eventToFire = OperationFinishedNotification;\n    if(null!=eventToFire)\n    {\n        OperationFinishedNotification(result);\n    }\n    return result;           \n} \n\nprivate string TakesALongTimeToProcess(string word)\n{\n    \/\/ This operation takes a while\n    Thread.Sleep(1000);\n    return word;\n}<\/code><\/pre><\/noscript><\/p>\n<p>Like before we want to change \u2018AwesomeBusinessOperation\u2019 to run asynchronously. Again this is not that hard. Add the async modifier and \u2018await\u2019 other asynchronous operations. The rest is the same as before. <script src=\"https:\/\/gist.github.com\/661651.js?file=MyBusinessLogic-2.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">public event Action&lt;string&gt; OperationFinishedNotification;\n\npublic async Task&lt;string&gt; AwesomeBusinessOperationAsync()\n{\n    var firstPart =await TakesALongTimeToProcess(&quot;Tons&quot;);\n    var secondPart = await TakesALongTimeToProcess(firstPart + &quot; of &quot;);\n    var result = await TakesALongTimeToProcess(secondPart + &quot;money&quot;);\n\n    var eventToFire = OperationFinishedNotification;\n    if(null!=eventToFire)\n    {\n        OperationFinishedNotification(result);\n    }\n    return result;           \n}\n\nprivate Task&lt;string&gt; TakesALongTimeToProcess(string word)\n{\n    \/\/ Remember, this is just a simulation\n    \/\/ Usually you would use some other async API here\n    return TaskEx.Run(() =&gt;\n    {\n        \/\/ This operation takes a while\n        Thread.Sleep(1000);\n        return word;\n\n    });\n}<\/code><\/pre><\/noscript><\/p>\n<p>Since our test is only interested in the event, we don\u2019t need to change the test. How cool is that? However the test fails. Oh oh, bad news =(.<\/p>\n<p><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/unit-test-failure.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/unit-test-failure.png\" alt=\"Test fails after making the method asynchronous\" title=\"unit-test-failure\" class=\"aligncenter size-full wp-image-1302\" width=\"626\" height=\"490\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/unit-test-failure.png 626w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2010\/11\/unit-test-failure-300x234.png 300w\" sizes=\"(max-width: 626px) 100vw, 626px\" \/><\/a><\/p>\n<p>Why does our test fail? Well the operation does actually what it&#8217;s supposed to do: It runs asynchronously. The code initiates our asynchronous operations and the returns to the caller. In our test it returns to our unit test. This test now checks if the event was called. But the operation which triggers the event is still running and hence the test fails. For our example we can fix this by waiting in the tests. This is possible since our method returns a task anyway. We can use the Wait-method on the task. After this change the test works again. <script src=\"https:\/\/gist.github.com\/661651.js?file=MyBusinessLogicTest-2.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">[Test]\npublic void ExpectEventToBeFired(){\n    var toTest = new MyBusinessLogic();\n    var eventFiredExpected = &quot;&quot;;\n    toTest.OperationFinishedNotification \n        += eventArgument =&gt;\n                    {\n                        eventFiredExpected = eventArgument;\n                    };\n    var result = toTest.AwesomeBusinessOperationAsync();\n    \/\/ just wait for the asynchronous operation\n    result.Wait();\n    Assert.AreEqual(&quot;Tons of money&quot;,eventFiredExpected);\n}<\/code><\/pre><\/noscript><\/p>\n<h2>Conclusion And Follow-Up<\/h2>\n<p>Well we&#8217;ve seen that some unit tests can easily be adapted for async operations. We&#8217;ve also seen that some async operations may break our tests and we need to introduce additional awaits.<\/p>\n<p>As you may noticed this isn&#8217;t the full story. We are still using rather na\u00efve examples. What if the async operation returns void and we cannot use the returned task to wait for completion? Does the synchronization really work correctly? There&#8217;s more to clearify. I&#8217;m going to tackle this issues in follow up post. Stay tuned.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Disclaimer: This post is based on the C# 5.0 CTP. Everything described here is subject to future changes. I\u2019ve already discussed some implications of the async feature in my previous&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[126],"tags":[21,200,24,199],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1289"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=1289"}],"version-history":[{"count":33,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1289\/revisions"}],"predecessor-version":[{"id":3915,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1289\/revisions\/3915"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=1289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=1289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=1289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}