2010-03-09 2 views
2

이것은 쉬운 문제인 것처럼 보이지만 내 검색을 수행하는 키워드를 찾지 못하는 것 같습니다.C# 라이브러리 클래스에 정적 메서드 호출 moqing

이 메서드 호출 내에서 모든 객체를 조롱하여 단위 테스트를 시도하고 있습니다. 나는이 일을 제외하고 내 자신의 모든 창조물에 그렇게 할 수 있어요 :

public void MyFunc(MyVarClass myVar) 
{ 
    Image picture; 
    ... 

    picture = Image.FromStream(new MemoryStream(myVar.ImageStream)); 

    ... 
} 

FromStream는 이미지 클래스의 정적 호출 (C#을의 일부)이다. 그렇다면 어떻게하면 단위 테스트에 이미지 스트림을 제공하고 싶지 않기 때문에 코드를 리팩터링하여이를 조롱 할 수 있을까요?

답변

1

모의 또는 스텁을 사용하여 단위 테스트에서 설정할 수있는 Func 유형 속성에 정적 함수를 래핑 할 수 있습니다.

public class MyClass 
{ 
    .. 

    public Func<Image, MemoryStream> ImageFromStream = 
            (stream) => Image.FromStream(stream); 


    public void MyFunc(MyVarClass myVar) 
    { 
     ... 

     picture = ImageFromStream(new MemoryStream(myVar.ImageStream)); 

     ... 
    } 


    .. 
} 
+0

인터페이스 아이디어로 포장하는 것 같아요, 내 코드를 통해 정적 호출의 여러 인스턴스를 가지고 있다면이 솔루션은 잘 확장되지 않습니다. 모든 정적 호출에 대해 함수를 만들어야합니다. 정적 메서드를 라이브러리 클래스에서 조롱 할 방법이 없습니까? – Joe

+0

다른 정적 메서드에 대해 다시 사용할 수있는 속성 만 만들어야합니다. 나는 TypeMock이 일리노이 주를 사용하여 정적 메서드를 모의 할 수 있다고 믿지만 자유롭지는 않다. 테스트 할 수있는 코드를 분리하는 것은 C#에서 상당히 많은 작업을 수행 할 수 있습니다. – tarn

+0

몇 가지 생각을하자면 제공되는 인터페이스와 함수 솔루션이 모두 엉망 이었지만이 함수 솔루션은 하나의 정적 함수를 조롱하기위한 새로운 인터페이스와 클래스를 만드는 것보다 적은 수의 라인을 사용했습니다. 그래서 나는 이걸 가지고 갈거야. 모든 해답을 가져 주셔서 감사합니다. – Joe

3

IImageLoader 인터페이스를 생성 할 수 있습니다. "일반"구현은 Image.FromStream을 호출하기 만하면되는 반면, 유닛 테스트 버전은 필요한 모든 작업을 수행 할 수 있습니다.

+0

이렇게하면 다른 클래스에 적용 할 정적 메서드 호출마다 인터페이스를 만들어야합니다. 이 작업을 수행하는 좀 더 우아한 방법이 필요합니다. – Joe

+1

아니, 런타임에 도움없이 정적으로 컴파일 된 언어로이 문제를 해결할 우아한 방법이 없습니다. 프로파일 링 CLR API (매우 복잡함)를 사용하여이를 수행 할 수있는 방법이 있습니다. 이것은 TypeMock이 작동하는 방식입니다. – CVertex

+1

CVertex의 TypeMock 사용 솔루션 외에도 실제로는 방법이 없습니다. 정적 방법과 단위 테스트는 실제로 잘 어울리지 않습니다. –

2

Moq 및 대부분의 다른 조롱 프레임 워크는 정적 방법 조롱을 지원하지 않습니다. 그러나 TypeMock은 정적 메서드를 조롱하는 것을 지원하며 구매하려는 경우 관심을 가질 수 있습니다. 그렇지 않으면 인터페이스가 조롱 될 수 있도록 리팩토링해야합니다 ...

+0

MSR의 두더지도이 공간에서 재생됩니다. –

1

Visual Studio 2010 전동 공구 Moles으로 확인할 수 있습니다. Moles 코드는 다음과 같습니다.

// replace Image.FromStream(MemoryStream) with a delegate 
MImage.FromStreamMemoryStream = stream => null;