Значение свойства заглушки MOQ для объекта "Any"

Я работаю над кодом, который следует шаблону инкапсуляции всех аргументов метода как объекта "запроса" и возврата объекта "ответа". Тем не менее, это создало некоторые проблемы, когда дело доходит до насмешек с 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 ответа

Решение

Что вы ищете это It.Is<T> метод, в котором вы можете указать любую функцию соответствия (Func<T, bool>) для аргумента.

Например, проверка ключа:

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

Я подозреваю, что вы могли бы сделать это с Custom Matchers.

Со страницы быстрого запуска moq:

// 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 победил меня, с (возможно) лучшим ответом. Ах хорошо.

Другие вопросы по тегам