2008-08-11 7 views
1

실패시에 throw되는 함수를 테스트하는 가장 좋은 방법은 무엇입니까? 또는 실패에 상당히 영향을받지 않는 기능을 테스트 할 수 있습니까?실패시 throw하는 함수 테스트

예를 들면; 포트를 올바르게 초기화 할 수없는 경우 생성자에서 throw하는 I/O 완료 포트 클래스가 있습니다. 이 초기화 프로그램 목록에서 CreateIoCompletionPort Win32 함수를 사용합니다. 핸들이 올바르게 설정되어 있지 않은 경우 (null 이외의 값), 생성자는 예외를 throw합니다. 나는이 기능이 실패한 것을 본 적이 없다.

내 질문은)는

입니다 그래서, 그들은 제대로 작동합니다 실패 할 경우이 (내 코드에서와 같은 기타 기능), 코드가 긴 공백을 포함하여 50 줄 것을 꽤 확신 시험해 볼만한 가치가있다.
b) 테스트 해 볼 가치가 있다면?
c) 단위 테스트를 거친 간단한 래퍼 클래스를 사용해야합니까?

b)에 대해서는 CreateIoCompletionPort를 재정의하고 값을 전달하는 방법에 대해 생각했습니다. 단위 테스트에서는 그것을 무시하고 특정 값이 전달되면 0을 반환하도록 만듭니다. 그러나 생성자에서 사용되므로 정적이어야합니다. 이것은 유효하거나 그렇지 않은 것 같습니까?

답변

2

오류 조건을 테스트하는 것이 좋습니다. 둘 다 클래스가 올바르게 예외를 throw하고 원하는 경우 예외가 클래스에서 제대로 처리된다는 점입니다.

이것은 생성자로 전달 된 객체에 대한 작업 인 경우 쉽게 수행 할 수 있습니다. 그냥 모의 객체로 전달합니다. 그렇지 않은 경우 기능을 보호 된 메서드로 옮기고 보호 된 메서드를 재정 의하여 내 오류 사례를 나타 내기 쉽습니다. 내가 예를 들어 자바를 사용하지만, 포트에 C#을 경우에 생각만큼 쉽게해야합니다 : 당신이 볼 수 있듯이

public class MyClass { 
    public MyClass() throws MyClassException { 
     // Whatever, including a call to invokeCreateIoCompletionPort 
    } 

    protected int invokeCreateIoCompletionPort(String str, int i) { 
     return StaticClass.createIoCompletionPort(str, i); 
    } 
} 

public class MyTest { 
    public void myTest() { 
     try { 
      new MyClass(); 
      fail("MyClassException was not thrown!"); 
     } catch (MyClassException e) { 
     } 
    } 

    private static class MyClassWrapper extends MyClass { 
     @Override 
     protected int invokeCreateIoCompletionPort(String str, int i) { 
      throw new ExpectedException(); 
     } 
    } 
} 

, 예외가 생성자에 의해 발생되고 있는지 여부를 테스트하기 위해 매우 쉽다 또는 메소드를 테스트 할 수 있으며, 예외를 throw 할 수있는 외부 클래스의 예외를 주입하는 것도 꽤 쉽습니다. 미안, 실제 메서드를 사용하지 않아서, 방금 사용했던 것처럼 소리가 나는지 설명하기 위해 이름을 사용했습니다. 테스트하려는 사운드를 테스트하는 방법은 무엇입니까?

기본적으로 노출하는 API 세부 정보는 일반적으로 테스트 할 수 있으며, 예외적 인 사례가 제대로 작동 하는지를 알고 싶다면 아마 테스트해야 할 것입니다.

1

I/O 완료 포트를 조롱 할 수있는 방법으로 코드를 작성하는 것이 좋습니다. I/O 객체에서 필요한 메소드를 노출하고 예상 한 것과 같은 일을 수행하는 테스트 및 구현을 테스트하는 인터페이스/추상 클래스를 만듭니다 (아마도 실패를 시뮬레이트하는 옵션).

AFAIK 종속성을 최소화하기 위해 단위 테스트시 외부 리소스를 조롱하는 것이 일반적입니다. 지정된 메시지 유형의와 함께 예외가 발생하는 경우

[Test, ExpectedException(typeof(SpecificException), "Exception's specific message")] 
public void TestWhichHasException() 
{ 
    CallMethodThatThrowsSpecificException(); 
} 

테스트 전달합니다 :

3

은 .NET에서이 일을하는 경우, 당신은 테스트에 추가 할 수 ExpectedException 속성이 있습니다. 속성에는 InnerExceptions 등을 포함한 다른 과부하가 있습니다.

0

저에게 C++ 같은 소리가납니다. Win32 함수를 모방하기 위해서는 솔기가 필요합니다. 예 :클래스에서 ::CreateIoCompletionPort()을 호출하는 보호 된 메서드 CreateIoCompletionPort()을 만들고 테스트에서는 I/O 완료 포트 클래스를 파생시킨 클래스를 만들고 CreateIoCompletionPort()을 재정의하여 NULL을 반환합니다. 프로덕션 클래스는 디자인 된 것처럼 동작하지만 여전히 CreateIoCompletionPort() 함수에서 실패를 시뮬레이트 할 수 있습니다.

이 기술은 Michael Feathers의 "Working with legacy code"에서 발췌 한 것입니다.

관련 문제