2014-09-30 2 views
3

У меня есть интерфейс, который содержит метод следующую подпись:Дразнящий из выражения с NSubstitute

TResult GetValue<T, TResult>(object key, Expression<Func<T, TResult>> property) where T : class; 

Используя Moq, я могу издеваться конкретный вызов этого метода, как это:

var repo = new Mock<IRepository>(); 
repo.Setup(r => r.GetValue<Customer, string>("SomeCustomerId", c => c.SecretAgentId)).Returns("SecretAgentId"); 

Тогда, когда я делаю этот вызов

repo.Object.GetValue<Customer, string>("SomeCustomerId", c => c.SecretAgentId); 

Tt возвращает "SecretAgentId", как я ожидал, так что все выглядит нормально.

Моя проблема заключается в том, что в нашем реальном коде производства мы используем NSubstitute, а не Moq. Я попытался, используя тот же тип установки здесь:

var repo = Substitute.For<ICrmRepository>(); 
repo.GetValue<Customer, string>("SomeCustomerId", c => c.SecretAgentId).Returns("SecretAgentId"); 

Однако, когда я делаю следующий вызов здесь

repo.GetValue<Customer, string>("SomeCustomerId", c => c.SecretAgentId); 

возвращает «» вместо "SecretAgentId"

Я попытался заменяющего c => c.SecretAgentId с Arg.Any<Expression<Func<Customer, string>>>() просто чтобы увидеть, работает ли он тогда, а затем возвращает "SecretAgentId", как и ожидалось. Но мне нужно проверить, что он вызывается с правильным выражением, а не только с любым выражением.

Так что мне нужно знать, можно ли заставить это работать в NSubstitute, и если да, то как?

ответ

3

Я думаю, что выражения оцениваются в NSubstitute в зависимости от их области охвата, поэтому объявления двух выражений не идентичны. Это похоже на ошибку, вы можете открыть проблему.

Однако вы можете взять выражение из декларации замещения, и она работает правильно:

private static void Main(string[] args) 
{ 
    Expression<Func<string, string>> myExpression = s => s.Length.ToString(); 
    var c = Substitute.For<IRepo>(); 
    c.GetValue<string, string>("c", myExpression).Returns("C"); 

    var result = c.GetValue<string, string>("c", myExpression); // outputs "C" 
} 
1

Я не могу вспомнить точный синтаксис, так что простите меня, если это не A1 правильно, и это немного запутано, но ...

Я считаю, что ты на правильном пути, когда вы пытались Arg.Any, однако попробуйте использовать Arg.Is как это:

Arg.Is<Expression<Func<Customer, string>>>(x => { 
    var m = ((Expression)x).Body as MemberExpression; 
    var p = m.Member as PropertyInfo; 
    return p.Name == "SecretAgentId"; 
});