目标C& OC Mock - 模拟类方法?

发布于 2024-10-31 19:19:41 字数 44 浏览 6 评论 0原文

我需要能够确定是否调用了类方法。 我怎样才能用 OCMock 做到这一点?

I need to be able to determine whether a class method was called or not.
How can I do this with OCMock?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

音盲 2024-11-07 19:19:41

从 OCMock 版本 2.1 开始,这是开箱即用的支持。现在,您可以使用与存根实例方法相同的方式存根类方法。

Starting with OCMock release 2.1 this is supported out of the box. You can now stub class methods in the same way as you stub instance methods.

感性不性感 2024-11-07 19:19:41

一种方法是将类方法包装在您自己的类的方法中。假设您的类必须调用 [SomeOtherClass classMethod:someString]。您可以在您的类上创建一个方法 invokeClassMethod:,如下所示:

-(NSString *)invokeClassMethod:(NSString *)someString {
    return [SomeOtherClass classMethod:someString];
}

然后在您的测试中,您创建一个部分模拟并期望 invokeClassMethod:

-(void)testSomething {
    id partialMock = [OCMockObject partialMockForObject:actual];
    [[[partialMock expect] andReturn:@"foo"] invokeClassMethod:@"bar"];

    [actual doSomething:@"bar"];

    [partialMock verify];
}

如果您想验证 invokeClassMethod 没有被调用,你可以抛出异常:

-(void)testSomethingElse {
    id partialMock = [OCMockObject partialMockForObject:actual];
    [[[partialMock stub] andThrow:[NSException exceptionWithName:@"foo" reason:@"Should not have called invokeClassMethod:" userInfo:nil] invokeClassMethod:OCMOCK_ANY];

    [actual doSomething:@"bar"];
}

如果调用invokeClassMethod,异常将导致测试失败。

One approach is to wrap the class method in a method on your own class. So let's say your class has to call [SomeOtherClass classMethod:someString]. You could create a method invokeClassMethod: on your class like this:

-(NSString *)invokeClassMethod:(NSString *)someString {
    return [SomeOtherClass classMethod:someString];
}

Then in your test, you create a partial mock and expect invokeClassMethod:

-(void)testSomething {
    id partialMock = [OCMockObject partialMockForObject:actual];
    [[[partialMock expect] andReturn:@"foo"] invokeClassMethod:@"bar"];

    [actual doSomething:@"bar"];

    [partialMock verify];
}

If you want to verify that invokeClassMethod isn't called, you can throw an exception:

-(void)testSomethingElse {
    id partialMock = [OCMockObject partialMockForObject:actual];
    [[[partialMock stub] andThrow:[NSException exceptionWithName:@"foo" reason:@"Should not have called invokeClassMethod:" userInfo:nil] invokeClassMethod:OCMOCK_ANY];

    [actual doSomething:@"bar"];
}

The excpetion will cause the test to fail if invokeClassMethod is called.

浅听莫相离 2024-11-07 19:19:41

正如 zneak 在对您的问题的评论中提到的,请查看 这个答案

从那里的评论中,查看类方法的这个基于块的实现搅动。

OCMock 似乎并不直接支持你想要做的事情,但是这个解决方案非常好!

As zneak mentioned in their comment to your question, have a look at this answer,

And from the comments there, checkout this block-based implementation of class method swizzling.

OCMock doesnt seem to directly support what you want to do, but this solution is quite nice!

夢归不見 2024-11-07 19:19:41

或者,假设您有类:

@interface ABCCleverClass : NSObject
+ (id)specialMethod;
@end

并且您想要模拟此类方法。一种选择是在此类上创建一个类别,用于定义和实现测试支持。然后,您可以将被测类中的类方法的实现与类别中的模拟方法交换。

#import <objc/runtime.h>

@interface ABCCleverClass (TestSupport)
+ (id)mockSpecialMethod;
@end

@implementation ABCCleverClass (TestSupport)

+ (void)load {
  Method original = class_getClassMethod([ABCCleverClass class], @selector(specialMethod));
  Method mocked = class_getClassMethod([ABCCleverClass class], @selector(mockSpecialMethod));
  method_exchangeImplementations(original, mocked);
}

+ (id)mockSpecialMethod {
  // Perform mock method. You may need to add more class methods
  // in order to configure this.
}

@end

Alternatively, lets assume that you have the class:

@interface ABCCleverClass : NSObject
+ (id)specialMethod;
@end

and you want to mock this class method. One option is to create a category on this class which defines and implements testing support. Then, you can swap the implementation of the class method in the class under test with your mock one from the category.

#import <objc/runtime.h>

@interface ABCCleverClass (TestSupport)
+ (id)mockSpecialMethod;
@end

@implementation ABCCleverClass (TestSupport)

+ (void)load {
  Method original = class_getClassMethod([ABCCleverClass class], @selector(specialMethod));
  Method mocked = class_getClassMethod([ABCCleverClass class], @selector(mockSpecialMethod));
  method_exchangeImplementations(original, mocked);
}

+ (id)mockSpecialMethod {
  // Perform mock method. You may need to add more class methods
  // in order to configure this.
}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文