“任意”对象上的MOQ存根属性值

时间:2013-06-06 12:47:45

标签: c# mocking moq stubbing moq-3

我正在研究一些代码,这些代码遵循将方法的所有参数封装为“请求”对象并返回“响应”对象的模式。但是,在使用MOQ进行模拟时,这会产生一些问题。例如:

public class Query : IQuery
{
    public QueryResponse Execute(QueryRequest request)
    {
        // get the customer...
        return new QueryResponse { Customer = customer };
    }
}

public class QueryRequest
{
    public string Key { get; set; }
}

public class QueryResponse
{
    public Customer Customer { get; set; }
}

...在我的测试中,我希望将查询存根,以便在给出密钥时返回客户

var customer = new Customer();
var key = "something";
var query = new Mock<ICustomerQuery>();

// I want to do something like this (but this does not work)
// i.e. I dont care what the request object that get passed is in but it must have the key value I want to give it

query.Setup(q => q.Execute(It.IsAny<QueryRequest>().Key = key)).Returns(new QueryResponse {Customer = customer});

MOQ中我想要的是什么?

2 个答案:

答案 0 :(得分:11)

您正在寻找It.Is<T>方法,您可以为参数指定任何匹配器函数(Func<T, bool>)。

例如检查密钥:

query.Setup(q => q.Execute(It.Is<QueryRequest>(q => q.Key == key)))
     .Returns(new QueryResponse {Customer = customer});

答案 1 :(得分:0)

我怀疑你可以使用Custom Matchers做到这一点。

来自moq's QuickStart page

// custom matchers
mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>();
...
public string IsLarge() 
{ 
  return Match.Create<string>(s => !String.IsNullOrEmpty(s) && s.Length > 100);
}

我怀疑你可以做类似的事情。创建一个使用Match.Create<QueryRequest>匹配您的密钥的方法,例如

public QueryRequest CorrectKey(string key)
{
    return Match.Create<QueryRequest>(qr => qr.Key == key);
}

然后

_query.Setup(q => q.Execute(CorrectKey(key))).Returns(new QueryResponse {Customer = customer});

注意:我没有尝试过这段代码,如果完全破坏,请原谅我。

哦,对于一些温和相关的自我宣传:正是这种复杂性让我对Moq和其他嘲弄工具感到困惑。这就是为什么我创建了一个模拟库,允许您使用普通代码检查方法参数:http://github.com/eteeselink/FakeThat。它正处于重大重构(和重命名)过程的中间,所以你可能想屏住呼吸。不过,我很高兴听到你的想法。

编辑:哦,@ nemesv用一个(可能)更好的答案打败了我。好吧。

相关问题