2013-09-26 6 views
2

저는 XCTest와 OCMock 2.2.1을 사용하여 단위 테스트를하고 있습니다. 내가 사용하는 번들 식별자를 얻는 클래스가 :부분적으로 조롱 된 객체에서 + [NSBundle bundleForClass :]를 호출하면 비인가 된 객체와 다른 결과가 반환됩니까?

예상대로 응용 프로그램이나 특히이 클래스의 단위 테스트를 실행하는 동안이 작동
NSString *bundleIdentifier = [[NSBundle bundleForClass:[self class]] bundleIdentifier]; 

.

다른 클래스에 대한 테스트를 수행하면서이 객체를 부분적으로 조롱했지만 번들 식별자가 실행되도록하는 메소드가 여전히 필요합니다.

내가보고하고하는 + [OCMockObject partialMockForObject:]에 객체의 인스턴스를 통과하기 전에이다 올바른 같습니다

(lldb) po myObject 
<MyObject: 0x1006ec480> 
(lldb) po [NSBundle bundleForClass:[myObject class]] 
NSBundle </Users/paynerc/Library/Developer/Xcode/DerivedData/xxxx/Build/Products/Debug/MyTests Tests.xctest> (loaded) 
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier] 
com.paynerc.MyBundle 

을 그러나, 나는 통과 후 myObject[OCMockObject partialMockForObject:myObject]으로 상황이 변화 : 사실

(lldb) po myObject 
<MyObject-0x1006ec480-401894396.880136: 0x1006ec480> 
(lldb) po [NSBundle bundleForClass:[myObject class]] 
NSBundle </Applications/Xcode.app/Contents/Developer/usr/bin> (loaded) 
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier] 
nil 

객체가 수정되고 부분 모의 마술을 포함하는 것이 합리적입니다. 이해가 안되는 것은 bundleForClass에 대한 호출이 반환하는 값을 변경 한 이유입니다.

bundleForClass이 MyObject 내에서 호출을 조롱하지 않고 원래 값을 계속 반환하도록하기 위해 할 수있는 일이 있습니까? 다른 단위 테스트에서 MyObject의 일부 모의가 필요한 다른 사용자가 bundleForClass의 스텁 된 구현을 제공해야한다는 것을 기억해야합니다.

현재 솔루션은 번들 식별자를 요청하고 결과를 검사하는 것입니다. 만약 nil이라면, [NSBundle allBundles]을 호출하고 non-nil bundleIdentifier를 찾을 때까지 반복한다. 그 동안 현재 ... 작동 ... 그것은 매우 강력하지 B) 끔찍한 무차별 적 힘 - C와) 단위 테스트를 지원하는 응용 프로그램 코드를 수정.

다른 사람이이 문제를 발견하고 더 나은 해결책을 생각해 냈습니까?

답변

3

런타임이 올바르게 작동합니다. 조롱 된 객체는 NSProxy의 하위 클래스이므로 객체의 isa과 번들 사이의 런타임 연결이 효과적으로 끊어집니다 (특히 isaClass을 가리키고 dyld API를 통해 조회하여 mach-o 이미지를 결정합니다). 에서로드 된 및 번들을 찾는 데 사용됩니다).

OCMockObject 프록시 (또는 하위 클래스 OCPartialMockObject)에 원본 클래스를 검색 할 수있는 API가있을 수 있습니다. 물론 테스트에만 사용해야하는 모의 호출로 코드를 오염시키는 것을 의미하는 코드를 사용해야합니다.

는 다른 방법으로, 클래스의 번들을 반환 어떤 번들/프레임 워크 /의 클래스 중 하나의 클래스 메소드를 구현합니다. 그것은 조롱 받아서는 안됩니다.

+0

청구서는 평소와 마찬가지입니다. 그러나 우리는 mock 객체의 동작을 변경하여 기대하는 바를 수행합니다. 이것은 진행중인 작업입니다. https://github.com/erikdoe/ocmock/pull/45 및 https://github.com/erikdoe/ocmock/commit/c7ed21cead25a78c98fd46e1f95defef4721e5e6 –

+0

을 참조하십시오. NSProxy 서브 클래스는 일반적으로 -isKindOfClass :를 구현하여 프록시 될 클래스에 대해 YES를 반환하고, OCClassMockObject도 다르지 않습니다.(비록 NSProxy 서브 클래스가 일반적으로 그러 하듯이 -class를 구현해야 할 수도 있지만). 여기서 문제는 원래 객체가 스스로 조롱당하는 것입니다. 부분적인 조롱 프로세스가 "isa"포인터를 변경하므로 -class 메소드의 반환 값이 달라 지므로 bundleForClass :가 망가집니다. 그러나 Erik이 말했듯이, OCMock의 다음 릴리스에서 수정되어야합니다. –

+0

@ CarlLindberg 설명해 주셔서 감사합니다. 이전에 OCMock * 구현을 살펴 보지 않았습니다. – bbum