2014-09-30 73 views
3

我有一个包含以下方法签名接口:嘲弄了表达NSubstitute

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

使用起订量,我可以嘲笑这种方法的这样一个特定的呼叫:

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"

我试着用Arg.Any<Expression<Func<Customer, string>>>()更换c => c.SecretAgentId只是为了看看它是否有效,然后按预期返回"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"; 
});