2014-12-18 2 views
0

Rhino Mock에 약간의 문제가 있습니다.Arg.Matches()가 기본값 (T)을 반환하지 않아야 함을 지정하는 방법

나는 (문자열 아래의 샘플에서) 객체를 기대하는 메소드를 가진 추상 클래스를 가지고있다. 이 메소드는 인수가 null인지 확인합니다.

public class Baz 
{ 
    private readonly Foo foo; 

    public Baz(Foo foo) 
    { 
     this.foo = foo; 
    } 

    public void DoWork(string s) 
    { 
     s = "xxx" + s; 
     this.foo.DoSomething(s); 
    } 
} 

내가 단위 테스트를하고 클래스 FooDoSomething가 올바른 인수로 호출되어 있는지 확인하려면 :

public abstract class Foo 
{ 
    public void DoSomething(string bar) 
    { 
     if (bar == null) 
     { 
      throw new ArgumentNullException("bar"); 
     } 
    } 
} 

나는 Foo를 사용하는 다른 클래스가 있습니다. 나는 이것에 Arg<T>.Matches()을 사용했습니다. 나는이 테스트를 실행하려고하면

[Test] 
    public void TestMethod() 
    { 
     var fooMock = MockRepository.GenerateMock<Foo>(); 
     var objectUnderTest = new Baz(fooMock); 

     fooMock.Expect(x => x.DoSomething(Arg<string>.Matches(Text.StartsWith("xxx")))) 
      .Repeat.Once(); 

     objectUnderTest.DoWork("hello"); 

     fooMock.VerifyAllExpectations(); 
    } 

은 지금의 Expect(...)에서 ArgumentNullException가 발생합니다. Rhino Mocks의 코드를 살펴보면 Match() -Method가 항상 default(T)을 반환한다는 것을 알았습니다.이 문자열은 문자열 (및 모든 다른 클래스)에 대해 null입니다. 따라서 DoSomething()의 수표는 ArgumentNullException입니다.

내가 알고 있듯이 Foo에 대한 인터페이스를 추출하여 해당 인터페이스의 모의 객체를 만들 수 있으므로 null 확인이 필요하지 않습니다. 하지만 Rhino Mocks에서 코드를 그대로두면 문제가 해결되는지 알기를 원합니다 (단위 테스트 제외 :-)).

답변

-1

테스트 코드 만 변경하면 문제를 해결할 수 없습니다. 테스트중인 코드는 테스트가 아닌 방식으로 작성되었습니다.

Rhino Mock에서 mocked/stubbed 메서드를 재정의해야하기 때문입니다. 나는. DoSomething()인터페이스 방법 (질문에서 설명한대로)이거나 가상 메소드이어야합니다.
오버라이드 가능한 경우 실제 메소드 DoSomething()Expect() 호출 내에서 트리거되지 않습니다.

두 옵션 모두 작동 할 수 있지만 테스트 변경시 코드가 필요합니다.

Foo 대신 IFoo과 같은 사용 인터페이스가 테스트에서 코드를 수정할 수 있다면 preferrable 방법입니다. 이것이 바로 dependency injection을 올바르게 구현해야하는 방법입니다.

관련 문제