Don’t Expose IList<T> Just So You Can Assert Against Its Contents
Lately I’ve been trying to return IEnumerable
With tools like Resharper, It’s easy to change the return types of the methods that you’re getting the collection from and use an IList
The good news is that there’s a super simple solution to this situation that does not require changing the IEnumerable
1: IEnumerable<MyObject> myEnumerator = someService.GetStuff();
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 2:</span> var myCollection = <span style="color: #0000ff">new</span> List<MyObject>(myEnumerator);</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 3:</span>  </pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 4:</span> [Test]</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 5:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> my_test()</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 6:</span> {</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 7:</span> myCollection.Count.ShouldBe(1);</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 8:</span> myCollection[0].ShouldEqual(myObject);</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 9:</span> <span style="color: #008000">//etc.</span></pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 10:</span> }</pre>
<p>
<!--CRLF--></div> </div>
<p>
 
</p>
<p>
If you’re doing interaction testing with an interface and a mock object, where the interface receives an IEnumerable<T>, you can still use this trick. For example, if I have this method on an interface defintion:
</p>
<div>
<div>
<pre><span style="color: #606060"> 1:</span> <span style="color: #0000ff">void</span> ShowProductCodes(IEnumerable<Lookup> productCodes);</pre>
<p>
<!--CRLF--></div> </div>
<p>
I can grab the output of this method via a stub and convert it to an IList<T>. Here’s one way to do it via RhinoMocks:
</p>
<div>
<div>
<pre><span style="color: #606060"> 1:</span> var view = Mock<IAssetClassificationView>();</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 2:</span> view.Stub(v => v.ShowProductCodes(Arg<IEnumerable<Lookup>>.Is.Anything))</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 3:</span> .Callback((IEnumerable<Lookup> lookups) =></pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 4:</span> {</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 5:</span> DisplayedProductCodes = <span style="color: #0000ff">new</span> List<Lookup>(lookups);</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 6:</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span>;</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 7:</span> });</pre>
<p>
<!--CRLF-->
</p>
<pre><span style="color: #606060"> 8:</span> <span style="color: #0000ff">return</span> view;</pre>
<p>
<!--CRLF--></div> </div>
<p>
Line 5 wraps up the IEnumerable<Lookup> into an IList<Lookup> object, letting me test the contents/count/etc on the collection.
</p>
<p>
Now you never need to worry about whether you can test the IEnumerable<T> when you are passing it around in your code. Just wrap it in an IList<T> at test time and call your tests the way you need to.
</p>
