How to mock class method (+)? [duplicate]

旧巷老猫 提交于 2019-12-04 01:38:50

问题


Need to write unit testing for the following code, I want to do mock for class method canMakePayments, return yes or no, so far no good method found dues to canMakePayments is a class method (+), seems all OCMock methods are all used for instance method (-).

You guys any suggestion or discussion will be appreciated. Thanks.

// SKPaymentQueue.h
// StoreKit
if ([SKPaymentQueue canMakePayments]){
   ....
}
else{
   ...
}

回答1:


Since you can't intercept the method by providing a different instance, what you can do for a class method is provide a different class. Something like this:

+ (Class)paymentQueueClass
{
    return [SKPaymentQueue class];
}

The point of call then becomes:

Class paymentQueueClass = [[self class] paymentQueueClass];
if ([paymentQueueClass canMakePayments])
...

This introduces a "testing seam," or a point of control, allowing us to specify a class other than SKPaymentQueue. Now let's make a replacement:

static BOOL fakeCanMakePayments;

@interface FakePaymentQueue : SKPaymentQueue
@end

@implementation FakePaymentQueue

+ (void)setFakeCanMakePayments:(BOOL)fakeValue
{
    fakeCanMakePayments = fakeValue;
}

+ (BOOL)canMakePayments
{
    return fakeCanMakePayments;
}

@end

Strictly speaking, this isn't a "mock object" -- it's a "fake object." The difference is that a mock object verifies how it's called. A fake object just provides stubbed results.

Now let's create a testing subclass of the original class we want to test.

@interface TestingSubclass : OriginalClass
@end

@implementation TestingSubclass

+ (Class)paymentQueueClass
{
    return [FakePaymentQueue class];
}

@end

So you see, this replaces SKPaymentQueue with FakePaymentQueue. Your tests can now run against TestingSubclass.




回答2:


One approach is to wrap the class method in your own instance method:

-(BOOL)canMakePayments {
    return [SKPaymentQueue canMakePayments];
}

Then you mock that method:

-(void)testCanHandlePaymentsDisabled {
    Foo *foo = [[Foo alloc] init];
    id mockFoo = [OCMockObject partialMockForObject:foo];
    BOOL paymentsEnabled = NO;
    [[[mockFoo stub] andReturnValue:OCMOCK_VALUE(paymentsEnabled)] canMakePayments];

    // set up expectations for payments disabled case
    ...

    [foo attemptPurchase];
}


来源:https://stackoverflow.com/questions/8427044/how-to-mock-class-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!