2013-04-15 2 views
2

is 연산자를 조롱 할 수 있습니까? 내 코드에는 클래스의 유형에 따라 논리가 있지만 값 자체는 공통 인터페이스로 클래스에 저장됩니다.모의 연산자는

기본적으로, 내가 뭘 원하는에 "모의"를 is 운영자, 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을 반환이다 다음과 같은 경우에만 true를 반환합니다.

  1. 확인중인 개체가 검사 할 유형의 인스턴스입니다.
  2. 검사 할 개체가 검사 할 형식의 하위 클래스입니다.
  3. 검사 할 개체가 검사 할 인터페이스 유형을 구현합니다.

디자인이 좋지 않으므로 실제로 Value의 인스턴스가 필요한 경우 IValue이 필요하지 않습니다.

요점은 구현이 아닌 추상화에 달려 있다는 것입니다. 그래서 당신은 IValue 인터페이스를 가지고 있어야합니다. TesterValue, MockValue 또는 그 밖의 것이 있으면주의해야합니다. IValue 인터페이스에 정의 된 메서드 및 속성에 따라 달라야합니다.

가짜를 만드는 요령은 특정 시나리오에서 Tester 클래스의 동작을 테스트하는 것입니다. 모의에서는 다음과 같이 많은 수의 더미 클래스를 만들 필요없이 해당 테스트를 받기 위해 Tester 객체의 동작을 지정할 수 있습니다. class FakeValueWhichDoes... : IValue을 테스트하십시오.

+0

+1, 불량 디자인에 동의합니다. 인터페이스의 모든 목적은 실제 구현을 사용하지 않는 것입니다. 매개 변수가 IValue 유형 인 경우 전체 코드 블록은 IValue에 의해 노출 된 것을 사용해야합니다. – ken2k

+2

귀하의 세 사례가 불완전합니다. 예를 들어,'object o = (Func ) (() => ""); bool b = o is Func ; 결과는 true이지만 세 가지 경우 중 하나를 만족하지 못합니다. –

+0

@EricLippert 그것을 지적 해 주셔서 감사합니다. 공변 (Covariance)을 언급하는 것을 잊었습니다. –