나는 또한 here으로 묘사 된 것을 달성하고 싶습니다. 즉 레거시 코드 내에 모의 객체를 만듭니다. 그러나 나는 대신 partial이 필요합니다.or strict 가짜입니다.레거시 코드에서 OCMock으로 개체를 부분적으로 조롱하는 방법은 무엇입니까?
예를 들어 loadScoresWithCompletionHandler:
의 스터브 버전을 구현하는 경우를 제외하고 정확히 GKLeaderbaord
과 같은 동작을하는 리더 보드를 고려해보십시오.
나는이 코드를 XCTestCase
안에 시도했지만 현재 런타임에 표시된 줄에 오류가 발생했습니다. OCMInvocationMatcher
은 EXC_BAD_ACCESS
오류를 발생시킵니다. 아마도 무한 재귀가 진행 중일 것입니다.
id leaderboardMock = OCMClassMock(GKLeaderboard.class);
OCMStub([leaderboardMock alloc])
.andReturn(OCMPartialMock([GKLeaderboard alloc]));
OCMStub([leaderboardMock loadScoresWithCompletionHandler: [OCMArg any]])
.andDo(^(NSInvocation *invocation) { /* ... */ });
// these parts normally nested inside legacy code
GKLeaderboard *leaderboard = /* raises EXC_BAD_ACCESS */
[[GKLeaderboard alloc] initWithPlayers: @[ GKLocalPlayer.localPlayer ]];
leaderboard.identifier = @"Test";
[leaderboard loadScoresWithCompletionHandler: nil /* ... */ ];
무엇이 잘못 되었나요? 그리고 부분 모형을 만들 수 있습니까? 지금 쯤
UPDATE 내가 할 수있는이 표시된 라인 (아주 명백하게) 무한 재귀가 발생할 수 있습니다 방법을 볼 수 있지만, 아직 그것을 피할 방법을 알고 (또는 중단)하지 않습니다.
UPDATE는 또한 OCMStub([leaderboardMock alloc]).andReturn([LeaderboardMock alloc])
와 (나 OCMStub([leaderboardMock initWithPlayers: [OCMArg any]]).andReturn([[LeaderboardMock alloc] initWithPlayers:nil])
있는) 전용 클래스에서 가져 오는 시도 어떠한 성공을 했어. 아마도 OCMock
은 init
의 레벨에서 마법을 실행합니다 (documentation은 "init
메서드를 스텁하는 것은 불가능합니다. 모의 자체로 구현되기 때문에") 따라서 이러한 시도는 alloc
(또는 initWithPlayers:
) 레벨에는 가질 수 없습니다. 원하는 효과.
문제는 (내가 지금 그것을 인식으로) 리더는 내가 건드릴 수 없어 레거시 코드에 깊은 만든 것입니다. 그러므로 나는 그것의 생성과 사용 사이 ('id leaderboardMock = OCMPartialMock (leaderboard); ')에 전화를 걸 수있는 방법이 없다. [here] (http://stackoverflow.com/q/18503604/1789384)도 참조하십시오. – Drux
'init' 메소드를 조롱 할 수는 없지만'initWithPlayers :'가 작동해야합니다. 그래서 alloc/init 조롱을 시도해보십시오. –
'OCMPartialMock' ('OCMClassMock'과 반대)을 호출하려면'leaderboard'의 인스턴스를 알아야합니다. 불행히도, 그것은 단지 레거시 코드베이스 내부에서 생성 된 후에 알려지며 일부 API에 노출되지 않습니다. – Drux