2013-01-19 3 views
3

그래서 나는 몇 가지 테스트 케이스를 작성했다. 이 클래스는 이러한 두 가지 방법이 있습니다테스트 케이스에서 메소드가 호출되는 클래스 모의

- (void)showNextNewsItem { 
    self.xmlUrl = self.nextNewsUrl; 
    [self loadWebViewContent]; 
} 

- (void)showPreviousNewsItem { 
    self.xmlUrl = self.previousNewsUrl; 
    [self loadWebViewContent]; 
} 

는 리팩토링 될 수 있습니다 이것은 매우 원시적이지만, 그럼에도 불구하고 난 그냥 확실 다음로드 다음 및 이전 부하 이전을 만들고 싶어. 그래서 나는 이런 내 SUT 클래스의 OCMockObject를 인스턴스화 OCMock을 사용

- (void)testShowNextOrPreviousItemShouldReloadWebView { 

    id mockSut = [OCMockObject mockForClass:[NewsItemDetailsViewController class]]; 

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] nextNewsUrl]; 
    [[mockSut expect] loadWebViewContent]; 

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] previousNewsUrl]; 
    [[mockSut expect] loadWebViewContent]; 

    [mockSut showNextNewsItem]; 
    [mockSut showPreviousNewsItem]; 

    [mockSut verify]; 
} 

문제는 실제로 확인하기 위해 뭔가를 할 방법을 호출하는 두 줄에있다. 이제 OCMock은 showNextNewsItemshowPreviousNewsItem을 호출 할 것이라고 예상하지 않습니다. 물론 테스트 중이므로 프로덕션 코드 자체에서만 특정 작업이 수행되기를 기대하기 때문에 예상하지 못합니다.

조롱 개념의 어느 부분을 제대로 이해하지 못 했습니까?

답변

2

일반적으로 테스트중인 클래스를 조롱하는 것은 혼란 스럽지만 원하는 경우 "부분적 모의 (partial mock)"가 필요하므로 스텁없이 메소드를 호출하고 일반 메소드를 실행할 수 있습니다.

이것은 OCMock에서 docs에 따라 지원되는 것으로 보입니다.

+0

고맙습니다 - 맞습니다. 그러나 유감스럽게도 iOS 프로젝트는 명확한 반환 값을 가진 함수 대신 "행동 중심"메소드를 축적하는 경향이 있습니다. 이 방법은 내가 예상 한 결과보다는 올바른 메서드 호출 만 테스트 할 수 있습니다. 어쩌면이 리팩토링에 대해 생각해야합니다. ;-) –

+0

당신 자신의 대답은 당신이 부분적인 모의로 이것을하는 방법을 알아 냈다고 제안하는 것 같습니다. 미안하지만 그것이 명확하지 않다면,하지만 당신이 정확하게 테스트하려고하는 수업을 조롱하지 않는 것이 낫다고 말하고 있었지만, 정확하게 가르쳐 주려고했습니다. 리팩토링은 거의 언제나 좋은 생각입니다. –

+0

맞습니다. 당신이 이것을 올린 것과 동시에 생각이 들었을 것입니다. 귀하의 대답을 정확하게 표시 할 것입니다 - 나는 단지 전체 코드를 주석에 게시하고 싶지 않습니다 (이것은 가능하지도 않습니다). 고마워요! –

2

해결책을 찾았습니다. 객체에서 partialMock을 사용하면 원하는 부분을 정확히 수행 할 수 있습니다. 이 방법으로 명시 적으로 정의한 호출을 조롱하고 "not-mocked"객체에서 테스트중인 메소드를 호출합니다.

- (void)testShowNextOrPreviousItemShouldReloadWebView { 

    NewsItemDetailsViewController *sut = [[NewsItemDetailsViewController alloc] init]; 

    id mockSut = [OCMockObject partialMockForObject:sut]; 

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] nextNewsUrl]; 
    [[mockSut expect] loadWebViewContent]; 

    [[[mockSut expect] andReturn:@"http://www.someurl.com"] previousNewsUrl]; 
    [[mockSut expect] loadWebViewContent]; 

    [sut showNextNewsItem]; 
    [sut showPreviousNewsItem]; 

    [mockSut verify]; 
}