Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The first lines of your list method are as follows:</p> <pre><code>public ViewResult List(string category, int page = 1) //Use default value { var productsToShow = (category == null) ? productRepository.GetProducts() : productRepository.GetProductsByCategoryTypeDescription(category); </code></pre> <p>When you call the list method in your test, it is as follows:</p> <pre><code>var result = controller.List("Sermons", 1); </code></pre> <p>Based on the call site, we can see that the <code>category</code> parameter is <strong>not null</strong>. This means that the List method will skip the <code>productRepository.GetProducts()</code> call and do the <code>productRepository.GetProductsByCategoryTypeDescription(category)</code> call instead.</p> <p>Looking at your helper that sets up the repository mock we see this:</p> <pre><code>public static IProductRepository MockProductRepository(params Product[] products) { // Generate an implementer of IProductRepository at runtime using Moq var mockProductRepos = new Mock&lt;IProductRepository&gt;(); mockProductRepos.Setup(x =&gt; x.GetProducts()).Returns(products.AsQueryable()); return mockProductRepos.Object; } </code></pre> <p>It's clear from this that the <code>GetProductsByCategoryTypeDescription</code> method on <code>IProductRepository</code> is not being set up, and will return either null or an empty <code>IEnumerable&lt;Product&gt;</code>. You'll need to explicitly set up this method to return the collection you want. I'd recommend either adding a new helper, or replacing the existing one, with something like this:</p> <pre><code>public static IProductRepository MockProductRepository(string category, params Product[] products) { // Generate an implementer of IProductRepository at runtime using Moq var mockProductRepos = new Mock&lt;IProductRepository&gt;(); mockProductRepos.Setup(x =&gt; x.GetProductsByCategoryTypeDescription(category)).Returns(products.AsQueryable()); return mockProductRepos.Object; } </code></pre> <p>Then change the unit test to use that helper. Add a category variable to the test to ensure that the "Sermons" value is only hard-coded in one place.</p> <pre><code>// Arrange: If two products are in two different categories... string category = "Sermons"; IProductRepository productRepository = UnitTestHelpers.MockProductRepository( category, new Sermon { Name = "Sermon1", ProductCategory = new ProductCategory { ProductCategoryId = 1, Description = "Sermons" } }, new Sermon { Name = "Sermon2", ProductCategory = new ProductCategory { ProductCategoryId = 2, Description = "Books" } } ); </code></pre> <p>Use the category variable again for the "Act" step:</p> <pre><code>// Act: ... then when we ask for one specific category var result = controller.List(category, 1); </code></pre> <p>This should resolve your zero products problem. Another thing to be aware of is that for this unit test you set up a mock <code>IProductCategoryRepository</code> but then don't appear to use it at all. Maybe there is some code not shown that requires it. But if not, then you should probably just use a plain, uninitialized mock (i.e. pass new <code>Mock&lt;IProductCategoryRepository&gt;().Object</code> directly to the controller constructor), to be clear that there is no dependency on that object involved in this particular test.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload