2012-02-07 16 views
5

我有下面的代碼在我的模擬接口有一個記錄器屬性,它是一類。設置通過設置模擬引起財產「的表達是不是一個方法調用」

我再試着設置這個類的一個屬性,但我得到了Expression is not a method invocation錯誤。你能幫忙嗎?

的錯誤是在運行的時候它去嘗試一個集枚舉屬性。它將引發與下面的堆棧跟蹤一個ArgumentException:

at Moq.ExpressionExtensions.ToMethodCall(LambdaExpression expression) 
    at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b() 
    at Moq.PexProtector.Invoke[T](Func`1 function) 
    at Moq.Mock.Setup[T,TResult](Mock mock, Expression`1 expression, Func`1 condition) 
    at Moq.Mock`1.Setup[TResult](Expression`1 expression) 

感謝

//Works 
var mock = new Moq.Mock<IEngine>(); 
//Works 
mock.Setup(x => x.Recorder).Returns(new Moq.Mock<Recorder>().Object); 
//Fails on the next line assigning a property value!!! 
mock.Setup(x => x.Recorder.RunState).Returns(Recorder.eRunStates.Play); 

更新 -我發現RunState是不是這是一個枚舉

+0

您能否告訴我們*您在哪裏得到錯誤?它是編譯時錯誤還是執行時錯誤,如果它是執行時錯誤,它何時發生? – 2012-02-07 15:25:57

+0

@JonSkeet完成! – Jon 2012-02-07 15:33:46

+0

那麼哪個呼叫失敗 - 第一個還是第二個? (如果是第一個,讓我們從圖片中刪除第二個......) – 2012-02-07 15:35:26

回答

6

我發現,創造記錄的模擬,然後模擬對象分配值似乎解決這個問題。不知道這是否是正確的做法。

var mockRecorder = new Moq.Mock<Recorder>(); 
mockRecorder.Object.RunState = Recorder.eRunStates.Play; 
4
一個屬性,但一個字段/成員

我想你應該返回您在第一部分中創建的第二部分模擬:

var mockRecorder = new Moq.Mock<Recorder>(); 
mock.Setup(x => x.Recorder).Returns(mockRecorder.Object); 
mockRecorder.Setup(x => x.RunState).Returns(Recorder.eRunStates.Play); 

這只是一個猜測,沒有使用Moq自己 - 但它是有道理的。

然而,這看起來像它最終將會是相當脆弱的。你可能想考慮在這裏使用假的 - 至少一個的對象,如果不是兩個。

編輯:縱觀documentation,另一種是:

// Moq will set up the hierarchy for you... 
mock.Setup(x => x.Recorder.RunState).Returns(Recorder.eRunStates.Play); 
+0

不幸的是,這會導致相同的錯誤。假的你是指手寫的嗎? – Jon 2012-02-07 15:21:34

+0

@Jon:是的。它感覺非常脆弱,依賴於被調用的特定屬性。 – 2012-02-07 15:23:46

+0

這是令人討厭的遺留代碼,我瀕臨放棄誠實 – Jon 2012-02-07 15:24:43

1

你需要做的模仿對象配置RunState屬性,而不是在設置。

var mockRecorder = new Mock<Recorder>(); 
mockRecorder.Setup(x => x.RunState).Returns(eRunStates.Play); 

mock.Setup(x => x.Recorder).Returns(mockRecorder.Object); 

編輯:僅供參考,您需要做的所有的模擬設置爲對象在這一點上創建的,並進一步設置不可能發生訪問.Object屬性之前。

此外,一些建議,它看起來像你的運行狀態的枚舉嵌套在你的記​​錄器類,我將它移動到一個單獨的類&另外刪除'e'前綴。

2

如果你在嘲笑使用SetupGet而不是設置這將工作

var mockRecorder = new Moq.Mock<Recorder>(); 
mock.SetupGet(x => x.Recorder).Returns(mockRecorder.Object); 
mockRecorder.SetupGet(x => x.RunState).Returns(Recorder.eRunStates.Play); 
+0

同樣的問題。已經注意到它的一個字段不是屬性 – Jon 2012-02-07 15:44:15

+0

那麼你需要一個模擬嗎? – Ciaran 2012-02-07 15:48:58

+0

是的,因爲我需要聲明IEngine中的方法被調用,但是這需要被模擬並傳遞到另一個類 – Jon 2012-02-07 15:51:23