我是Moq和Nunit的新单位测试新手。我有一个简单的单元测试来获取产品列表。但测试结果没有达到预期效果。
ProductManagementController操作是:
public ViewResult Index(int? id)
{
return View(_ProductRepo.GetProductList(id));
}
ProductRepository是:
public IList<Product> GetProductList(int? id)
{
if (id == null)
{
return (db.Products).ToList();
}
else
{
return db.Products.Where(i => i.CategoryId == id).ToList();
}
}
我有两个测试设置,但只有第一个测试(获取所有产品列表)没问题。
[TestFixture]
public class Test_ProductManagement
{
private List<Product> products;
private List<Category> categories;
private Mock<IProductRepository> mockProducts;
private ProductManagementController target;
[TestFixtureSetUp]
public void Initialize()
{
images = new List<Product> {
new Product{Id = 1, Name = "Boat", CategoryId = 1 },
new Product{Id = 2, Name = "Picture Frame",CategoryId = 2 }
};
categories = new List<Category> {
new Category { Id = 1, Name = "Outdoors" },
new Category { Id = 2, Name = "Housewares" }
};
mockProducts = new Mock<IProductRepository>();
mockProducts.Setup(m => m.GetProductList(It.IsAny<int>())).Returns(products);
target = new ProductManagementController(mockProducts.Object);
}
[Test]
public void Index_Contains_All_Products()
{
//Action
List<Product> result = ((IEnumerable<Product>)target.Index(It.IsAny<int>()).ViewData.Model).ToList();
//Assert
Assert.AreEqual(2, result.Length);
Assert.AreEqual("Boat", result[0].Name);
Assert.AreEqual("Picture Frame", result[1].Name);
}
[Test]
public void Index_Get_ImageList_By_CategoryId()
{ //Arrange
int id = 2;
//Action
List<Product> result = ((IEnumerable<Product>)target.Index(id).ViewData.Model).ToList();
//Assert
Assert.AreEqual(1, result.Count());
Assert.AreEqual("Picture Frame", result[0].Name);
}
第二次测试总是返回包含2个产品的完整产品列表,而我只希望从Assert.AreEqual(1,result.Count());
返回1个
我无法弄清楚为什么测试代码总是将id作为上述索引调用中的空参数:target.Index(id)
。但是,我的所有项目代码都在浏览器中正确运行。
有没有人有线索?感谢。
答案 0 :(得分:1)
我无法弄清楚为什么测试代码总是将id作为上述索引调用中的null参数:target.Index(id)
没有。您没有显示所有代码(特别是您的控制器如何处理存储库注入),并且您似乎至少重命名了products
/ images
字段,但代码工作正常。
您拨打target.Index(id)
,然后拨打_ProductRepo.GetProductList(id)
。我假设这是你的模拟被调用,你Setup()
总是返回整个产品列表。
模拟完全符合您的要求,此代码中未使用ProductRepository
,因此您的if (id == null)
永远不会被执行。
为了解决这个问题,您必须在每个测试方法中以不同方式Setup()
模拟,或提前设置两种情况:
mockProducts.Setup(m => m.GetProductList(null)).Returns(products);
mockProducts.Setup(m => m.GetProductList(2)).Returns(new List<Product>{products[1]});
当然,您希望设置后一个调用稍微不那么具体,但我希望您能看到可以解决此问题的地方。