2013-07-29 5 views
4

마침내 내가 작업하고있는 프로젝트에 일부 TDD가 부과되어 가장자리로 빠져 나옵니다. 원하는 코드는 알고 있지만 방법은 알지 못합니다. 이OCMock 테스트 개체가 할당되고 메서드가 호출됩니다.

을 :)위한 시험은 내가 찾고 구현은 다음과 같습니다

- (void) doSomething 
{ 
    FooBuilder *foo = [[FooBuilder alloc] init]; 
    [foo doSomethingElseWithCompletionBlock:^{ 
     [self somethingDone]; 
    }]; 
} 

그래서 나는 내 테스트가) 시험 방법은 다음 호출을 새로운 FooBuilder와 b) 그 방법을 할당하는 확인하려면 새로운 객체에 대한 메소드.

어떻게해야합니까? 나는 alloc 클래스 방법을 조롱하려고 시도했지만, 그 길은 광기가 있다는 것을 신속하게 결정한 길로 시작했다.

참고이 테스트에서는 FooBuilder 자체를 테스트하지 않고 공동 작업 만 수행합니다.

답변

1

일반적으로 의존성 주입은 "이 개체를 묻는 대신 여기에서 사용하십시오."라고 말하는 완전한 형식의 개체를 제공하는 데 사용됩니다. 그러나이 경우 새 객체를 인스턴스화하는 기능이 필요합니다. 따라서 객체를 삽입하는 대신 클래스를 삽입해야합니다. "특정 클래스를 만드는 대신 여기에서 하나를 인스턴스화하십시오."

종속 삽입의 두 가지 주요 형태가 있습니다 : "생성자 삽입"(Objective-C가 할당과 초기화로 구분 되더라도 "생성자"라는 용어를 사용합니다)와 "속성 삽입". 그것은 종속성을 만들기 때문에,

@property (nonatomic, strong) Class fooBuilderClass; 

생성자 주입 명확 : 속성의 등급을 지정 속성 주입 용

- (instancetype)initWithFooBuilderClass:(Class)fooBuilderClass; 

:

생성자 주입 들어, 이니셜의 클래스를 지정할 분명한. 그러나 속성 주입을 선호 할 수도 있습니다. 때때로 나는 마음을 바꾸면서 다른쪽으로 방향과 리팩토링을 시작한다.

어느 쪽이든 -initWithFooBuilderClass:을 호출하거나 속성을 [FooBuilderClass class]으로 설정하는 기본 이니셜 라이저를 사용할 수 있습니다.

다음 doSomething은 다음과 같이 시작합니다 :

- (void)doSomething 
{ 
    id foo = [[self.fooBuilderClass alloc] init]; 
    ... 
+0

존, 관심과 자세한 답변을 주셔서 감사합니다.하지만 여기에 뭔가 빠졌습니다. 테스트중인 클래스와'FooBuilder' 클래스 사이의 연결을 문제로 진단합니다.이렇게함으로써, 당신이 뭔가 더 단순하게 만드는 것처럼 느껴집니다. 나는 Foos를 표시하는 객체 막대를 가지고 있습니다. 이렇게하려면 FooBuilder를 사용하여 Foo를 빌드해야합니다. 내가 테스트를 더 쉽게하기 위해 필요하지 않은 보편성을 소개하라고 요구하는 것처럼 느껴진다. – dpassage

+0

오늘 아침에 문제가 실제로 클래스의 종속성 주입이라는 것을 깨달았습니다. 그래서 나는 내 대답을 완전히 다시 썼다. 크기에 따라 사용해보십시오. ... 너무 복잡하게 느껴질 경우 알려 주시면 더 자세히 설명하겠습니다. –

+0

나는 아직도 내가 묻고있는 것을 얻지 못하고 있다고 생각한다. 내 질문은 실제로 테스트중인 개체가 올바른 아웃 바운드 호출을 수행하도록 OCMock API를 구동하는 방법에 관한 것입니다. 아직도 필요없는 클래스에 일반성을 주입하려고합니다. – dpassage

0

내가 인수로 완료 블록 소요 FooBuilder에 새로운 클래스 메소드를 추가하여이 문제를 해결 끝났다. 그래서 인스턴스화와 메소드 호출을 테스트 대상 객체에서 공동 작업자 객체로 효과적으로 옮겼습니다. 이제는 단일 클래스 메서드 호출을 조롱 할 수 있습니다.

나는 이것이 내가 시작했던 것보다 약간 더 나은 디자인이라고 생각한다; 새로운 FooBuilder이 될 필요가있는 세부 사항은 이제 클래스의 사용자로부터 숨겨집니다. 그것은 또한 매우 간단합니다.

내 피조물과 FooBuilder 클래스 간의 강력한 결합을 유지한다는 특성이 있습니다. 어쩌면 그것은 저를 길 아래로 물 것입니다 - 그러나 나는 YAGNI가 그것을하지 않을 내기를하고 있습니다.

+0

뭔가 도움이 되었기 때문에 기쁩니다. 그러나 당신은 다른 곳에서도 똑같은 문제에 직면하게 될 것이고, 의존성 주입 (Dependency Injection)에 의존해야 할 것입니다. 여기에 다른 DI 예제가 있습니다. http://stackoverflow.com/questions/13711911/unit-testing-example-with-ocunit/ –

+0

확신 할 수있는 좋은 기술입니다. 그러나이 경우 일반성이 코드를 이해하기 어렵게한다는 점을 실제로 느꼈습니다. 도와 주셔서 감사합니다 - 이미 내 애플 리케이션에서 귀하의 웹 사이트에서 몇 가지 힌트를 사용하고 있습니다 :) – dpassage