【发布时间】:2013-07-10 12:33:19
【问题描述】:
有没有办法设置和验证使用带 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());
}
Thet 测试在 Assert 处失败并抛出空引用异常,因为 GetByFilter 方法从未被调用。
如果我改用这个
[Setup]
public void SetUp()
{
productsQuery.Setup(x => x.GetByFilter(It.IsAny<Expression<Func<Product, bool>>>())).Returns(new Product() { Title = "Good product", ... });
}
测试通过了 Assert 部分,但这次是 Verify that failed 表示它从未被调用。
有没有办法使用特定表达式而不是使用通用 It.IsAny<>() 来设置方法调用?
更新
我也在 cmets 中尝试了 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);
}
【问题讨论】:
-
您能否将 lambda 表达式分配给一个变量并在 Setup 和 Verify 调用中使用它?
-
不走运。用您的建议更新问题
-
我可能误解了您要执行的操作,但如果您只是想验证设置是否匹配,您不能只使用 VerifyAll 吗?
-
我可以猜到,但无论如何都不会调用设置。
-
从哪里获得 NRE?