문제

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

일부 데이터를 가져오기 위해 별도의 도우미를 호출한 다음 이를 변환하는 "LoadData" 메서드가 있습니다(변환된 결과를 테스트하고 싶습니다).

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

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

Helper.GetSomeData() 메서드에서 알려진 결과를 얻고 싶습니다.예상되는 결과를 강제하기 위해 모의 프레임워크(Rhino Mocks에 대한 경험이 상당히 제한되어 있지만 무엇이든 열려 있음)를 사용할 수 있습니까?그렇다면 어떻게?

*편집 - 예 예상대로 원하는 해킹을 달성할 수 없었습니다. 데이터를 설정하는 더 나은 방법을 찾아야 합니다.

도움이 되었습니까?

해결책

내가 아는 한, Helper 개체에 대한 인터페이스나 기본 추상 클래스를 만들어야 합니다.Rhino Mocks를 사용하면 원하는 값을 반환할 수 있습니다.

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

다른 팁

거기에 문제가 있습니다.이것이 코드의 단순화된 시나리오인지는 모르겠지만 Helper 클래스가 그런 방식으로 사용되면 코드를 테스트할 수 없습니다.먼저 Helper 클래스를 직접 사용하므로 모의로 대체할 수 없어.둘째, 정적 메서드를 호출합니다.저는 C#에 대해 모르지만 Java에서는 정적 메서드를 재정의할 수 없습니다..

더미 GetSomeData() 메서드를 사용하여 모의 개체를 삽입할 수 있으려면 일부 리팩토링을 수행해야 합니다.

이 단순화된 코드 버전에서는 직접적인 답변을 제공하기가 어렵습니다.몇 가지 옵션이 있습니다:

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

단순히 Helper 클래스에 대한 인터페이스를 생성하는 것에 주의하세요. 메소드를 통해 주입합니다.이는 구현 세부 사항을 노출할 수 있습니다.클라이언트가 구현을 제공해야 하는 이유 공익사업 간단한 작업을 호출하는 클래스?이는 MyClass 클라이언트의 복잡성을 증가시킵니다.

가지고 있는 것을 다음과 같이 변환하는 것이 좋습니다.

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 클래스인 것처럼 사용한다는 것을 알고 있습니다.

이제 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();
}

궁금한 점이 있으면 언제든지 댓글을 남겨주세요.(그런데 이 코드가 모두 작동하는지 전혀 모르겠습니다. 브라우저에 입력했을 뿐이며 주로 개념을 설명하고 있습니다.)

코드를 리팩터링하지 않고도 메서드 호출을 "가짜"로 만들 수 있는 Typemock Isolator를 살펴보는 것이 좋습니다.저는 해당 회사의 개발자이지만 디자인을 변경하지 않기로 선택하려면 솔루션이 가능합니다.

로이 블로그 :ISerialized.com

예, 조롱 프레임워크가 바로 여러분이 찾고 있는 것입니다.특정 모의/스텁 클래스가 반환되기를 원하는 방식을 기록/정리할 수 있습니다.

Rhino Mocks, Typemock 및 Moq는 모두 이 작업을 수행하는 데 좋은 옵션입니다.

스티븐 월터의 포스트 Rhino Mocks 사용에 대한 내용은 제가 처음 Rhino Mocks를 사용하기 시작했을 때 많은 도움이 되었습니다.

나는 다음과 같은 것을 시도할 것입니다:

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

이렇게 하면 MOQ 등을 사용하여 도우미 클래스를 모형화할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top