2011-04-14 5 views
23

처음으로 과 반환 값을 OCMock 스텁에 추가하면 해당 반환 값이 돌로 설정됩니다. 예 :OCMock 스텁의 반환 값을 어떻게 바꿀 수 있습니까?

id physics = [OCMockObject niceMockForClass:[DynamicPhysicsComponent class] 
Entity *testEntity = [Entity entityWithPhysicsComponent:physics]; 
CGPoint velocity1 = CGPointMake(100, 100); 
CGPoint velocity2 = CGPointZero; 
[[[physics stub] andReturnValue:OCMOCK_VALUE(velocity1)] getCurrentVelocity]; 
[testEntity update:0.1]; 
[[[physics stub] andReturnValue:OCMOCK_VALUE(velocity2)] getCurrentVelocity]; 
[testEntity update:0.1]; 

[testEntity update]에서 스터브 된 메서드가 호출됩니다. 그러나 stubbed 메서드가 velocity1 값을 반환 할 때마다 메서드 반환 값을 설정하는 두 번째 시도가 적용되지 않는다고 생각합니다.

OCMock에서이 작업을 수행 할 수있는 방법이 있습니까?

답변

37

방법이 stub이면 메서드 호출 횟수와 상관없이 항상 지정된 방법으로 작동해야한다는 것입니다. 당신이 stub에 필요한 경우

CGPoint velocity1 = CGPointMake(100, 100); 
CGPoint velocity2 = CGPointZero; 
[[[physics expect] andReturnValue:OCMOCK_VALUE(velocity1)] getCurrentVelocity]; 
[testEntity update:0.1]; 
[[[physics expect] andReturnValue:OCMOCK_VALUE(velocity2)] getCurrentVelocity]; 
[testEntity update:0.1]; 

또는, (예를 들어, 방법은 전혀 호출되지 않을 경우), 당신은 단지 모의을 다시 만들 수 있습니다 :이 문제를 해결하는 가장 쉬운 방법은 stubexpect에 변경하는 것입니다 : 당신은 돌의 반환 값을 설정하는 stub

CGPoint velocity1 = CGPointMake(100, 100); 
CGPoint velocity2 = CGPointZero; 
[[[physics stub] andReturnValue:OCMOCK_VALUE(velocity1)] getCurrentVelocity]; 
[testEntity update:0.1]; 
[physics verify]; 

physics = [OCMockObject mockForClass:[Physics class]]; 
[[[physics stub] andReturnValue:OCMOCK_VALUE(velocity2)] getCurrentVelocity]; 
[testEntity update:0.1]; 
[physics verify]; 
+0

내가 검증 할 필요가 없기 때문에 expect를 사용하지는 않았지만 첫 번째 예제에서와 같이 조롱 된 메소드 동작을 변경하기 위해 그것을 사용하면 내 경우에 잘 작동한다. 감사. – Cris

+2

두 번째 예제에서는 스텁 된 메소드와 함께 사용할 때'verify'의 목적은 무엇입니까? – Cris

+0

검증이 필요하지 않을 수도 있습니다. 나는 단지 새로운 모의 과제를 할당하기 전에 모의 테스트 (테스트에 적절하다면, 다른 기대가 있었는지 말하기)를 검증하라는 것을 지적하려고했다. –

25

사실 당신은 andReturn 또는 andReturnValue 사용하는 경우. 언제든지 andDo 메서드를 사용하여 반환 된 값을 변경할 수 있습니다. 이것은 expect 이상의 방법으로 메소드가 호출되는 횟수를 알아야합니다. 여기 코드는이 작업을 수행합니다 :

__weak TestClass *weakSelf = self; 
[[[physics stub] andDo:^(NSInvocation *invocation) { 
    NSValue *result = [NSValue valueWithCGPoint:weakSelf.currentVelocity]; 
    [invocation setReturnValue:&result]; 
}] getCurrentVelocity]; 
+3

stubbed 메서드를 호출해야하는 횟수 (-expect와 같이)를 수행하지 않아도되므로이 대답이 더 마음에 듭니다. – George

1

을 나는 CipherCom 내가 자신을 다양한 값을 반환하는 도우미 클래스를 만들 선호 찾기 정답이 있다고 생각하지만. 과거에 NSInvocation에 문제가있었습니다.

@interface TestHelper : NSObject 
@property (nonatomic, assign) CGPoint velocity; 
- (CGPoint)getCurrentVelocity; 
@end 

@implementation TestHelper 
- (CGPoint)getCurrentVelocity 
{ 
    return self.velocity; 
} 
@end 

그런 다음 내 테스트 클래스에서 나는 TestHelper에 대한 개인 멤버 변수를 가질 것 및 setUp 방법에 내가 할 줄 : 나는 속도를 설정할 수 있습니다 내 시험의 각

self.testHelper = [TestHelper new]; 

[[[physics stub] andCall:@selector(getCurrentVelocity) onObject:self.testHelper] 
       getCurrentVelocity]; 

그 방법을 테스트를 위해 내가 원하는 것.

self.testHelper.velocity = CGPointMake(100, 200);

1

는 여러 번 호출 할 때 어느 쪽도/andReturnValue/andDoandReturn가 오버라이드 (override)하지되지 않는 것 같습니다. 내 해결 방법은 테스트 클래스에 속성을 추가하고 조롱 된 객체가 반환해야하는 것을 제어하는 ​​것입니다. 예를 들어 조롱 된 객체의 isAvailable 속성의 경우 코드는 다음과 같습니다.

@interface MyTest: XCTestCase 
@property BOOL stubbedIsAvailable; 
@end 

@implementation MyTest 

- (void)setUp { 
    [OCMStub([myMockedObject isAvailable]) andDo:^(NSInvocation invocation) { 
     BOOL retVal = self.stubbedIsAvailable; 
     [invocation setReturnValue:&retVal]; 
    } 
} 

- (void)testBehaviourWhenIsAvailable { 
    self.stubbedIsAvailable = YES; 
    // test the unit 
} 

- (void)testBehaviourWhenIsNotAvailable { 
    self.stubbedIsAvailable = NOT; 
    // test the unit 
} 
관련 문제