2009-05-03 9 views
3

네트워크를 사용하는 코드 (특정하려면 NSURLConnection 클래스)를 테스트하고 싶습니다.NSURLConnection을 이용한 단위 테스트

- (id) buildConnection 
{ 
    // some more code and then: 
    return [NSURLConnection …]; 
} 

- (void) startNetworkSync 
{ 
    id connection = [self buildConnection]; 
    //… 
} 

단위 테스트에서 내가 즉, 네트워킹을 제거하고 싶습니다 : 코드 (의이 NetworkManager를 부르 자)이 같은 비트가 보인다. NSURLConnection 객체를 모의 객체로 바꿉니다. 어떻게해야합니까?

스텁으로 buildConnection 메서드를 대체 할 NetworkManager의 부분 모의 만들기를 시도했습니다. 문제는 외부 세계의 스텁 메시지 인 OCMock에 의한 부분적 모의입니다. startNetworkSync에서 buildConnection을 보내면 스텁이 아니라 원본 메서드가 호출됩니다.

나는 범주를 통해 NetworkManager 클래스의 원숭이 패치를 시도했습니다. 이 방법을 사용하면 buildConnection 메서드를 다른 코드로 쉽게 재정의하고 NSURLConnection 실제 코드를 스텁으로 바꿀 수 있습니다. 문제는 테스트에서 스텁 된 연결을 얻을 수있는 간단한 방법이 없다는 것입니다. 연결은 NetworkManager의 개인 부분입니다.

그런 다음 NetworkManager의 하위 클래스를 만들고 buildConnection 메서드를 재정의하고 인스턴스 변수와 만든 연결에 대한 접근자를 추가 할 수 있습니다. 하지만 이것은 많은 코드처럼 보입니다.

어떻게 해결할 수 있습니까? NetworkManager 클래스 디자인을 깨끗하게 유지하고 테스트에서 많은 마법이나 많은 코드가 필요하지 않은 솔루션을 찾고 있습니다.

답변

3

이것은 의존성 주입이 해결하도록 설계된 것입니다. 대신 startNetworkSyncWithConnection:(NSURLConnection*)을 사용하면 모의 연결로 메소드를 쉽게 테스트 할 수 있습니다. 클라이언트 용 API를 변경하지 않으려면 startNetworkSync을 인수로 [self buildConnection]이라는 새로운 메소드를 호출하는 래퍼로 유지할 수도 있습니다.

+0

좋아요, 나는이 방법으로 다소 성과가 있습니다. 클라이언트는 네트워크에 대해 아무것도 모르고 데이터 만 보내고 받지만 테스트에 도움이되는 프로세스에 '외부'연결을 주입하는 방법을 추가했습니다. 감사. – zoul

+0

@ zoul, 솔루션 코드를 붙여주세요. 감사! – ma11hew28

2

실제 부분 모의를 지원하도록 OCMock을 수정했습니다 (repo on GitHub 참조).

+0

감사합니다. 나는 이미 문제를 해결했지만 실제 부분적인 모의가 유용 할 것이다. 코드를 바닐라 OCMock과 병합 할 수 있습니까? – zoul

+0

예, OCMock의 작성자가 병합 중입니다. 그는 병합 중에 더 깨끗하게하려고 노력할 것입니다. –

+0

이 병합되었습니다 아직? 그렇다면이를 수행하는 방법에 대한 예를 제공해주십시오. – ma11hew28

0

최근에 사용한 또 다른 해결책은 네트워킹 인터페이스를 완전히 추상화하는 것입니다. 클래스가 네트워크에서 일부 데이터를 필요로하는 경우, 아마 명시 적으로 프로토콜로 모델링 할 수있는 서버의 서비스와 상호 작용 :

@protocol SomeNetworkService 
- (NSArray*) allAvailableFoos; 
- (void) insertNewFoo: (Foo*) foo; 
@end 

그리고 당신은 진정한 HTTP 구현 및 테스트를해야합니다. 이것은 더 많은 작업을 의미하지만 훨씬 더 나은 테스트 가능성을 의미합니다. 테스트 네트워크 레이어는 필요한 모든 작업을 수행 할 수 있으므로 테스트가 덜 쉽고 훨씬 편리합니다.

관련 문제