I am following along with the SportsStore application in Apress' Pro ASP.Net MVC 3 Framework.
This is a very simple example with a very simple Unit Test.
Here is the controller:
/////////////////////////////////////////////
public class ProductController : Controller
{
public int PageSize = 4; // We will change this later
private IProductRepository repository;
public ProductController(IProductRepository productRepository)
{
repository = productRepository;
}
public ViewResult List(int page = 1)
{
return View(repository.Products
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize));
}
}
/////////////////////////////////////////////
Here is the Unit Test ////////////////////////////////////////
[TestMethod]
public void Can_Pagninate()
{
// Arrage
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Product[] {
new Product { ProductID = 1, Name = "P1" },
new Product { ProductID = 1, Name = "P2" },
new Product { ProductID = 1, Name = "P3" },
new Product { ProductID = 1, Name = "P4" },
new Product { ProductID = 1, Name = "P5" },
}.AsQueryable());
// Create a and make the page size 3 items
ProductController controller = new ProductController(mock.Object);
controller.PageSize = 3;
// Action
IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model;
// Assert
Product[] prodArray = result.ToArray();
Assert.IsTrue(prodArray.Length == 2);
Assert.AreEqual(prodArray[0].Name, "P4");
Assert.AreEqual(prodArray[1].Name, "P5");
}
The assert is failing with the exception:
Test method SportsStore.UnitTests.ProductControllerTests.Can_Pagninate threw exception: System.ArgumentNullException: Value cannot be null. Parameter name: source
Here is the wierd thing.
If I place a break point here: IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model;
I see this,
controller.List(2).Model
base
Non-Public members
Results View
[0]
Name "P4" ProductID "1"
[1]
Name "P5" ProductID "1"
But when I continue on and finish the test, result gets assinged null and it crashes.
Why is the model returning null to result in:
IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model;
But I used Assert.IsNotNull(result.ViewData.Model) and it fails because the Model in inline code returns null.
But as I said, if I put a break point and inspect the result, I can hover over and inspect it and open the results of the LINQ query and see all the data, so I don't understand why these lines fail:
I Tried it by running in VS. Can you please Try it in your by copying the exact code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication4.Controllers
{
public class ProductController : Controller
{
public int PageSize = 4; // We will change this later
private IProductRepository repository;
public ProductController(IProductRepository productRepository)
{
repository = productRepository;
}
public ViewResult List(int page = 1)
{
return View(repository.Products.OrderBy(p => p.ProductId)
.Skip((page - 1) * PageSize)
.Take(PageSize));
}
}
public interface IProductRepository
{
IEnumerable<Products> Products { get; set; }
}
public class Products
{
public int ProductId;
public string Name;
}
}
UnitTest
[TestMethod]
public void Can_Pagninate()
{
// Arrage
Mock<IProductRepository> mock = new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new Products[] {
new Products { ProductId = 1, Name = "P1" },
new Products { ProductId = 1, Name = "P2" },
new Products { ProductId = 1, Name = "P3" },
new Products { ProductId = 1, Name = "P4" },
new Products { ProductId = 1, Name = "P5" },
}.AsQueryable());
// Create a and make the page size 3 items
ProductController controller = new ProductController(mock.Object);
controller.PageSize = 3;
// Action
IEnumerable<Products> result = (IEnumerable<Products>)controller.List(2).Model;
// Assert
Products[] prodArray = result.ToArray();
Assert.IsTrue(prodArray.Length == 2);
Assert.AreEqual(prodArray[0].Name, "P4");
Assert.AreEqual(prodArray[1].Name, "P5");
}
IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model;
// results in an invalid cast exception. The line should read:
IEnumerable<Prodcut> result = ((ProductsListViewModel)controller.List(2).Model).Products;
ProductListViewModel wasn't created at time when you read the book. Just skip this part and later you will create it by following the book.
After few days struggle on this, I didn't find any answer throughout the internet. Finally I got the reason. The book's code is correct. The reason of this happened to my situation was. I used different version of Syste.Web.Mvc in my Web project (v3) and
UnitTest project (v4). This doesn’t cause error at runtime just doesn’t return ActionResult or ViewResult due to incompatibility.
I wish no one else would waste time on same issue I had.
smiller781
Member
172 Points
199 Posts
Unit Test returning null for results, but I can see them in debugger.
Jun 16, 2012 02:50 PM|LINK
I am following along with the SportsStore application in Apress' Pro ASP.Net MVC 3 Framework.
This is a very simple example with a very simple Unit Test.
Here is the controller:
/////////////////////////////////////////////
public class ProductController : Controller { public int PageSize = 4; // We will change this later private IProductRepository repository; public ProductController(IProductRepository productRepository) { repository = productRepository; } public ViewResult List(int page = 1) { return View(repository.Products .OrderBy(p => p.ProductID) .Skip((page - 1) * PageSize) .Take(PageSize)); } } /////////////////////////////////////////////[TestMethod] public void Can_Pagninate() { // Arrage Mock<IProductRepository> mock = new Mock<IProductRepository>(); mock.Setup(m => m.Products).Returns(new Product[] { new Product { ProductID = 1, Name = "P1" }, new Product { ProductID = 1, Name = "P2" }, new Product { ProductID = 1, Name = "P3" }, new Product { ProductID = 1, Name = "P4" }, new Product { ProductID = 1, Name = "P5" }, }.AsQueryable()); // Create a and make the page size 3 items ProductController controller = new ProductController(mock.Object); controller.PageSize = 3; // Action IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model; // Assert Product[] prodArray = result.ToArray(); Assert.IsTrue(prodArray.Length == 2); Assert.AreEqual(prodArray[0].Name, "P4"); Assert.AreEqual(prodArray[1].Name, "P5"); }//////////////////////////////////////////////////////////////
The assert is failing with the exception:
Test method SportsStore.UnitTests.ProductControllerTests.Can_Pagninate threw exception: System.ArgumentNullException: Value cannot be null. Parameter name: source
Here is the wierd thing.
If I place a break point here: IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model;
I see this,
controller.List(2).Model
base
Non-Public members
Results View
[0]
Name "P4" ProductID "1"
[1]
Name "P5" ProductID "1"
But when I continue on and finish the test, result gets assinged null and it crashes.
Why is the model returning null to result in:
IEnumerable<Product> result = (IEnumerable<Product>)controller.List(2).Model;
CPrakash82
All-Star
18284 Points
2841 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Jun 16, 2012 06:24 PM|LINK
Change few lines in your unit test method, like below,
var result = controller.List(2);
//assert
var viewresult = Assert.IsType<ViewResult>(result); Assert.NotNull(result.ViewData.Model);
IEnumerable<Product> productResult = (IEnumerable<Product>)result.ViewData.Model;
Thanks,
smiller781
Member
172 Points
199 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Jun 17, 2012 02:10 PM|LINK
Thanks but I am using Visual Studio Test Tools.
I don't think Assert has the IsType<T> method.
But I used Assert.IsNotNull(result.ViewData.Model) and it fails because the Model in inline code returns null.
But as I said, if I put a break point and inspect the result, I can hover over and inspect it and open the results of the LINQ query and see all the data, so I don't understand why these lines fail:
Product[] prodArray = result.ToArray();
Assert.IsTrue(prodArray.Length == 2)
Assert.AreEqual(prodArray[0].Name, "P4")
And why it thinks result is null when I can see the results in the debugger watch window.
It's rediculous.
smiller781
Member
172 Points
199 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Jun 18, 2012 02:59 PM|LINK
So I think the problem is that the reultis a LINQ Query:
- controller.List(2).Model {SportsStore.Domain.Entities.Product[].OrderBy(p => p.ProductID).Skip(3).Take(3)} object {System.Linq.EnumerableQuery<SportsStore.Domain.Entities.Product>}
It just won't execute in real time for the UNIT TEST but exicutes in the watch window.
Man, what is missing here?
CPrakash82
All-Star
18284 Points
2841 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Jun 19, 2012 01:06 AM|LINK
Linq works in deffered execution, can you try doing F11 and step into controller's List method at this line and see what it is doing?
controller.List(2)
I am not sure why it is happending debugging might help, otherwise I see no reason, why your linq not executes.
Thanks,
dhanekula
Member
101 Points
37 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Jun 19, 2012 01:38 AM|LINK
I Tried it by running in VS. Can you please Try it in your by copying the exact code.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcApplication4.Controllers { public class ProductController : Controller { public int PageSize = 4; // We will change this later private IProductRepository repository; public ProductController(IProductRepository productRepository) { repository = productRepository; } public ViewResult List(int page = 1) { return View(repository.Products.OrderBy(p => p.ProductId) .Skip((page - 1) * PageSize) .Take(PageSize)); } } public interface IProductRepository { IEnumerable<Products> Products { get; set; } } public class Products { public int ProductId; public string Name; } } UnitTest [TestMethod] public void Can_Pagninate() { // Arrage Mock<IProductRepository> mock = new Mock<IProductRepository>(); mock.Setup(m => m.Products).Returns(new Products[] { new Products { ProductId = 1, Name = "P1" }, new Products { ProductId = 1, Name = "P2" }, new Products { ProductId = 1, Name = "P3" }, new Products { ProductId = 1, Name = "P4" }, new Products { ProductId = 1, Name = "P5" }, }.AsQueryable()); // Create a and make the page size 3 items ProductController controller = new ProductController(mock.Object); controller.PageSize = 3; // Action IEnumerable<Products> result = (IEnumerable<Products>)controller.List(2).Model; // Assert Products[] prodArray = result.ToArray(); Assert.IsTrue(prodArray.Length == 2); Assert.AreEqual(prodArray[0].Name, "P4"); Assert.AreEqual(prodArray[1].Name, "P5"); }View
@model IEnumerable<MvcApplication4.Controllers.Products>
@{
ViewBag.Title = "title";
Layout = "_Layout";
}
<h2>title</h2>
SnowFox108
Member
4 Points
2 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Nov 26, 2012 01:15 AM|LINK
This is Error of book
ProductListViewModel wasn't created at time when you read the book. Just skip this part and later you will create it by following the book.
SnowFox108
Member
4 Points
2 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Dec 04, 2012 01:32 AM|LINK
After few days struggle on this, I didn't find any answer throughout the internet. Finally I got the reason. The book's code is correct. The reason of this happened to my situation was. I used different version of Syste.Web.Mvc in my Web project (v3) and UnitTest project (v4). This doesn’t cause error at runtime just doesn’t return ActionResult or ViewResult due to incompatibility.
I wish no one else would waste time on same issue I had.
bweber89
Member
486 Points
119 Posts
Re: Unit Test returning null for results, but I can see them in debugger.
Feb 10, 2013 07:42 AM|LINK
Hi SnowFox108
Thanks to your great answer I have been able to solve it also! Thanks a lot!
Cheers
Junior Software Developer
AceChoi
Member
2 Points
1 Post
Re: Unit Test returning null for results, but I can see them in debugger.
Feb 27, 2013 08:12 AM|LINK
Hi
SnowFox108
I changed "System.Web.MVC" 4.0.0.0 to "System.Web.MVC 3.0.0.0".
I solved it.
Thanks to your great answer.