2013-04-15 63 views
2

是否可以模擬is運營商?在我的代碼中,邏輯取決於它的類型,但是這個值本身作爲通用接口存儲在類中。模擬運營商

基本上,我想要做的就是通過定義模擬到是IValue返回true,但is Value

public class Value : IValue 
{ 
} 

public interface IValue 
{ 
} 
public class Tester 
{ 
    public bool CheckIfValue(IValue value) 
    { 
     return value is Value; 
    } 
} 

[Test] 
public void TestIfValue() 
{ 
    Tester tester = new Tester(); 

    var value = MockRepository.GenerateStub<IValue>(); 
    // can I add anything here which will make CheckIfValue return true? 

    bool isValue = tester.CheckIfValue(value); 
    Assert.That(isValue, Is.True); 
} 
+0

'MockRepository.GenerateStub ()'返回不是'Value'的'IValue'實現嗎? – ken2k

+0

@ ken2k - 是的,它會在運行時創建一個類,它使用Castle.DynamicProxy框架實現該接口。 –

回答

6

返回true不,這是不可能的「模擬」的is操作,is會僅在以下情況下返回true:

  1. 被檢查的對象是要檢查的類型的實例。
  2. 被檢查的對象是被檢查類型的子類。
  3. 被檢查的對象實現了被檢查的接口類型。

您的設計很糟糕,如果您確實需要它作爲Value的實例,則不需要任何IValue

重點是取決於抽象而不是實現,這就是爲什麼你有IValue接口開始。 Tester不應該在乎它是否得到Value,MockValue或其他任何東西,它應該僅取決於IValue接口中定義的方法和屬性。

點創建一個模擬的是測試在一個特定的場景中你Tester類的行爲,模擬允許您指定Tester收到對測試對象的行爲,而無需創建大量虛擬類如class FakeValueWhichDoes... : IValue爲了測試它。

+0

+1,同意糟糕的設計。接口的全部目的是不使用實際的實現。如果參數是IValue類型,那麼整個代碼塊應該只使用IValue公開的內容。 – ken2k

+2

你的三個案例是不完整的FYI。例如,對象o =(Func )(()=>「」); bool b = o是Func ;'結果是正確的,但不符合你的三種情況。 –

+0

@EricLippert感謝您指出,我忘記提及協變。 –