有没有一种方法可以使用Moq设置和验证使用表达式的方法调用?
第一次尝试是我想让它工作的方式,而第二次尝试是一个“补丁”,让Assert
部分工作(但验证部分仍然失败)。
string goodUrl = "good-product-url";
[Setup]
public void SetUp()
{
productsQuery.Setup(x => x.GetByFilter(m=>m.Url== goodUrl).Returns(new Product() { Title = "Good product", ... });
}
[Test]
public void MyTest()
{
var controller = GetController();
var result = ((ViewResult)controller.Detail(goodUrl)).Model as ProductViewModel;
Assert.AreEqual("Good product", result.Title);
productsQuery.Verify(x => x.GetByFilter(t => t.Url == goodUrl), Times.Once());
}
这个测试在Assert
失败并抛出了空引用异常,因为从未调用GetByFilter方法。
如果我使用这个:
[Setup]
public void SetUp()
{
productsQuery.Setup(x => x.GetByFilter(It.IsAny<Expression<Func<Product, bool>>>())).Returns(new Product() { Title = "Good product", ... });
}
测试通过了断言部分,但是这次验证失败并提示从未被调用。是否有一种方法可以设置具有特定表达式的方法调用,而不是使用通用的
It.IsAny<>()
?更新:
我还尝试了评论中Ufuk Hacıoğulları的建议,并创建了以下内容。
Expression<Func<Product, bool>> goodUrlExpression = x => x.UrlRewrite == "GoodUrl";
[Setup]
public void SetUp()
{
productsQuery.Setup(x => x.GetByFilter(goodUrlExpression)).Returns(new Product() { Title = "Good product", ... });
}
[Test]
public void MyTest()
{
...
productsQuery.Verify(x => x.GetByFilter(goodUrlExpression), Times.Once());
}
但我遇到了空引用异常,就像第一次尝试一样。
我的控制器代码如下:
public ActionResult Detail(string urlRewrite)
{
//Here, during tests, I get the null reference exception
var entity = productQueries.GetByFilter(x => x.UrlRewrite == urlRewrite);
var model = new ProductDetailViewModel() { UrlRewrite = entity.UrlRewrite, Culture = entity.Culture, Title = entity.Title };
return View(model);
}