2008-09-18 4 views
9

다른 메서드 내에서 호출 된 메서드의 결과를 위조하는 방법을 찾으려고합니다.조롱 방법 결과

데이터를 얻기 위해 별도의 도우미를 호출 한 다음 변환합니다 (변환 된 결과를 테스트하는 데 관심이 있습니다).

그래서 나는 다음과 같은 코드가 있습니다

public class MyClass(){ 
    public void LoadData(){ 
    SomeProperty = Helper.GetSomeData(); 
} 
public object SomeProperty {get;set;} 
} 

내가 Helper.GetSomeData() 메소드에서 알려진 결과를 갖고 싶어. 조롱 프레임 워크를 사용할 수 있습니까 (저는 Rhino Mock에 대한 경험이 제한적이지만 다른 것에 대해 공개적으로 기대되는 결과를 얻을 수 있습니까?). 그렇다면 어떻게?

* 편집 - 예상대로 내가 원하는 해킹을 달성 할 수 없으므로 데이터를 설정하는 더 좋은 방법을 찾아야 할 것입니다.

+1

보세요 : http://stackoverflow.com/questions/90851/is-it-just-me-or-are-interfaces-overused –

답변

2

필자가 아는 한 Helper 객체의 인터페이스 또는 기본 추상 클래스를 만들어야합니다. Rhino Mocks를 사용하면 원하는 값을 반환 할 수 있습니다.

또는 일반적으로 Helper 개체에서 검색하는 데이터를 매개 변수로 사용할 수있는 LoadData에 대한 오버로드를 추가 할 수 있습니다. 이것은 더 쉬울 수도 있습니다.

0

예, 조롱 프레임 워크가 원하는 것입니다. 특정 조롱/스텁 클래스를 반환하는 방법을 기록/정렬 할 수 있습니다.

Rhino Mocks, Typemock 및 Moq가이를 수행하기위한 좋은 옵션입니다.

Steven Walther's post Rhino Mocks를 처음 사용했을 때 Rhino Mock을 사용하면 Rhino Mocks를 처음 사용했을 때 많은 도움이되었습니다.

+0

AFAIK, Helper가 정상적인 클래스 인 경우, 당신은 그 방법을 조롱 할 수 없다. –

10

문제가 있습니다. 이것이 단순한 코드 시나리오인지는 모르겠지만, Helper 클래스가 그런 식으로 사용된다면 코드는 테스트 할 수 없습니다. 첫째, Helper 클래스가 직접 사용되므로 은 모의 객체으로 바꿀 수 없습니다. 둘째, 정적 메서드를 호출하는 것입니다. C#에 대해 잘 모르지만 Java에서는 은 정적 메서드을 재정의 할 수 없습니다.

모의 객체에 더미 GetSomeData() 메소드를 삽입하려면 리팩터링을해야합니다.

코드의 단순화 된 버전에서는 정답을 제시하기가 어렵습니다. 다음과 같은 몇 가지 옵션이 있습니다.

  • 도우미 클래스의 인터페이스를 만들고 클라이언트가 도우미 구현을 MyClass 클래스에 삽입 할 수있는 방법을 제공하십시오. 그러나 Helper가 실제로는 유틸리티 클래스 일 경우 많은 의미가 없습니다.
  • MyClass에서 getSomeData라는 보호 된 메서드를 만들고 Helper.LoadSomeData 만 호출하도록합니다. 그런 다음 getSomeData에 대한 LoadData의 Helper.LoadSomeData에 대한 호출을 바꿉니다. 이제 getSomeData 메소드를 모의 해 더미 값을 반환 할 수 있습니다.

단순히 클래스 헬퍼 및 방법을 통해 주입하는 인터페이스를 생성주의. 이로 인해 구현 세부 사항이 노출 될 수 있습니다. 왜 클라이언트가 유틸리티 클래스의 구현을 제공해야 간단한 조작을 호출 할 수 있습니까? 이렇게하면 MyClass 클라이언트의 복잡성이 증가합니다.당신이 예를 MOQ에 사용 헬퍼 클래스를 조롱 할 수

public class MyClass(){ 
    public void LoadData(IHelper helper){ 
    SomeProperty = helper.GetSomeData(); 
} 

이 방법 :

+0

경고와 관련하여 ... 이것은 실제로 반전이라고합니다. 네가 올바르게하면 나쁜 것이 아니다. :) –

+1

예, 저는 그 용어를 압니다. 예, 올바르게 끝나면 매우 좋습니다. 여기서는 그렇지 않습니다. –

0

나는 이런 식으로 뭔가를 시도 할 것입니다.

8

난 당신이 이런 일에 무엇을 변환하는 것이 좋습니다 :

public class MyClass() 
{ 
    private IHelper _helper; 

    public MyClass() 
    { 
     //Default constructor normal code would use. 
     this._helper = new Helper(); 
    } 

    public MyClass(IHelper helper) 
    { 
     if(helper == null) 
     { 
      throw new NullException(); //I forget the exact name but you get my drift ;) 
     } 
     this._helper = helper; 
    } 

    public void LoadData() 
    { 
     SomeProperty = this._helper.GetSomeData(); 
    } 
    public object SomeProperty {get;set;} 
} 

지금 클래스는 의존성 주입으로 알려진 지원합니다. 이렇게하면 도우미 클래스의 구현을 삽입 할 수 있으며 클래스가 인터페이스에만 의존하면됩니다. 이 모의를 할 때 IHelper 인터페이스를 사용하는 모의 객체를 생성자에게 전달하면 클래스가 실제 Helper 클래스 인 것처럼 사용하게됩니다.

헬퍼 클래스를 정적 ​​클래스로 사용하는 경우 프록시/어댑터 패턴을 사용하고 IHelper 인터페이스를 지원하는 다른 클래스로 정적 클래스를 래핑하는 것이 좋습니다. 몹시 떠들어 대다).

이 단계를 더 진행하려면 수정 된 클래스에서 기본 도우미 구현을 완전히 제거하고 IoC (Inversion of Control) 컨테이너를 사용할 수 있습니다. 만약 당신이 처음이라면, 나는이 여분의 모든 번거 로움이 왜 가치가있는 지 (IMHO인지)의 기초에 우선 초점을 둘 것을 권한다.

단위 테스트는이 사이비 코드처럼 보일 것입니다 :

public Amazing_Mocking_Test() 
{ 
    //Mock object setup 
    MockObject mockery = new MockObject(); 
    IHelper myMock = (IHelper)mockery.createMockObject<IHelper>(); 
    mockery.On(myMock).Expect("GetSomeData").WithNoArguments().Return(Anything); 

    //The actual test 
    MyClass testClass = new MyClass(myMock); 
    testClass.LoadData(); 

    //Ensure the mock had all of it's expectations met. 
    mockery.VerifyExpectations(); 
} 

은 질문이있는 경우 의견을 주시기 바랍니다. (그런데이 코드가 모두 작동하는 경우 단서가 없습니다. 브라우저에 입력 한 코드는 개념을 주로 설명하고 있습니다.)

2

코드를 리팩터링하지 않고도 메서드 호출을 "fake"할 수있는 Typemock Isolator를 살펴볼 수 있습니다. 이 www.Typemock.com

로이 블로그에서의 그 회사에 dev에,하지만 당신은 (테스트 용이성을 위해 그것을 변경하지 않는 또는 강제) 설계를 변경하지 않도록 선택하고 싶을 경우 솔루션은 실행 가능 : ISerializable.com