2013-06-01 8 views
1

나는 네트워크를 수행하기위한 간단한 클래스를 가지고있다. 그것은 싱글 톤이며 내부에 NSOperationQueue을 캡슐화합니다. 클래스 '사용자가 네트워크에서 데이터를 가져 오는 메소드를 호출 할 때,이 클래스는 NSOperation에서 상속받은 연산 클래스의 적절한 인스턴스를 생성하여이를 설정하고 수행을 위해 대기열에 추가합니다. 분명히, 그 수행은 분리 된 스레드에서 비동기 적으로 수행됩니다. NSOperation 네트워크에서 데이터를 가져온 후 상속 된 객체가 내 네트워크 클래스에 알리고 관심있는 대리인에게 데이터가 완료되거나 오류가 있음을 알립니다.비동기 호출을 mock 및 미리 정의 된 답변으로 바꾸는 방법은 무엇입니까?

질문 : 네트워크 클래스 논리를 확인하기위한 단위 테스트는 어떻게합니까? 또한 실제로 서버 측 동작을 테스트하고 싶지 않습니다. 난 그냥 서버에 실제 비동기 호출을 모의 및 테스트 처리기의 동작 후 미리 정의 된 답변을 바꿀 싶어요. 클래스가 작동하는지 서버 측이 아닌지 확인하고 싶습니다. 나는 그런 것들을 테스트하기 위해 일반적으로 논리를 이해하지만, OCMock을 사용하기 위해 약간 혼란 스럽습니다. 최상의 답은 코드 예입니다. 유닛 테스트를 위해 OCUnit과 OCMock을 사용하고 있습니다.

또한 기사 나 github 링크가 완벽 할 것입니다.

답변

3

모든 비동기 호출이 클래스의 내부 메소드를 거치는 경우 객체에 부분 모의 객체를 만들고 해당 메소드에서 stub/expect를 사용하면됩니다. 그런 다음 public 메소드를 정상적으로 호출하고 mock을 사용하여 내부 메소드가 호출되었는지 확인할 수 있습니다. partial mock을 사용하면 실제 구현이 호출되지 않으므로 네트워크 활동이 발생하지 않아야합니다.

나머지 절반에 대해서는 비동기 작업에서의 콜백 (call-backs)은 단순히 테스트에서 직접 호출되는 메소드를 호출 한 다음 클래스가 올바른지 확인합니다. OCUnit이 선언 된 상태를 확인합니다 , 또는 콜백을 다른 모의와 함께 사용하는 경우.

1

내가 OCMock에 관한 것임을 알았지 만, 내가 이것을 Kiwi으로 성공적으로 처리했다는 것을 알았습니다. 키위와 shouldEventually를 사용하여, 그것은 그 선택기가 호출되기 전에 (기본값은 1 초) 시간을 기다릴 필요가 있음을 알 수 있도록

it(@"should refresh the client's temporary API key if it is stale before sending the request", ^{ 
    ISLDataServiceAdd *addRequest = [ISLDataServiceAdd withRecord:@{ISLFieldContact_FirstName: @"Jason"} table:ISLTableContact]; 

    [[clientMock shouldEventually] receive:@selector(apiKey) andReturn:VALID_API_KEY]; 
    [[clientMock shouldEventually] receive:@selector(hasTemporaryAPIKey) andReturn:theValue(YES)]; 
    [[clientMock shouldEventually] receive:@selector(isTemporaryAPIKeyStale) andReturn:theValue(YES)]; 
    [[clientMock shouldEventually] receive:@selector(refreshTemporaryAPIKeyAndWait:)]; 

    [addRequest sendRequestUsingClient:clientMock completion:nil failure:nil]; 
}); 

sendRequestUsingClient:completion:failure:는 비동기 호출입니다.

+0

Chris, 답변 해 주셔서 감사합니다. 현재 iOS에 대한 단위 테스트를 조사 중이며이 작업을 너무 크게 설정하고 있습니다.)). 지금 키위를 사용하지는 않지만 아마도이 기능에서 할 것입니다. 지금은 문제를 해결하는 방법을 찾았습니다. 난 그냥 메서드를 대체하거나 그 비슷한 것을하지 않고 필요한 메서드를 직접 호출합니다. 어쨌든 당신의 도움을 많이 주셔서 감사합니다, 아마도 당신의 대답은 나에게 도움이 될 것입니다. 아니면 다른 사람에게 도움이 될 것입니다. –