2014-09-30 70 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"; 
});