zap*_*aph 1 unit-testing objective-c ocunit ocmock ios
我试图测试一个实例化实例的方法MFMailComposeViewController.被测试的方法调用的多种方法MFMailComposeViewController,包括setSubject:.
我想测试setSubject是否发送了一个特定的NSString,在本例中是@"Test Message".
无论我为模拟存根中的预期字符串指定什么,都没有失败.
在单元测试类中:
#import <OCMock/OCMock.h>
- (void)testEmail {
TestClass *testInstance = [[TestClass alloc] init];
id mock = [OCMockObject mockForClass:[MFMailComposeViewController class]];
[[mock stub] setSubject:@"Test Message"];
[testInstance testMethod];
}
Run Code Online (Sandbox Code Playgroud)
在TestClass中:
- (void)testMethod {
MFMailComposeViewController *mailComposeVC = [[MFMailComposeViewController alloc] init];
[mailComposeVC setSubject:@"Bad Message"];
}
Test Suite 'Email_Tests' started at 2011-09-17 18:12:21 +0000
Test Case '-[Email_Tests testEmail]' started.
Test Case '-[Email_Tests testEmail]' passed (0.041 seconds).
Run Code Online (Sandbox Code Playgroud)
测试应该失败.
我在iOS模拟器中对此进行测试,并在设备上获得相同的结果.
我究竟做错了什么?有没有办法实现这个目标?
您创建了一个模拟,但从未将其传递给测试中的类,或者让模拟器验证自己.你需要某种形式的依赖注入来说,"而不是使用MFMailComposeViewController,使用我给你的另一件事."
这是一种方法.在被测试的类中,不是直接分配MFMailComposeViewController,而是通过工厂方法获取它,如下所示:
@interface TestClass : NSObject
- (void)testMethod;
// Factory methods
+ (id)mailComposeViewController;
@end
Run Code Online (Sandbox Code Playgroud)
这是实施.您正在泄漏,请注意工厂方法返回一个自动释放的对象.
- (void)testMethod {
MFMailComposeViewController *mailComposeVC =
[[self class] mailComposeViewController];
[mailComposeVC setSubject:@"Bad Message"];
}
+ (id)mailComposeViewController {
return [[[MFMailComposeViewController alloc] init] autorelease];
}
Run Code Online (Sandbox Code Playgroud)
在测试方面,我们创建一个覆盖工厂方法的测试子类,以便它提供我们想要的任何内容:
@interface TestingTestClass : TestClass
@property(nonatomic, assign) id mockMailComposeViewController;
@end
@implementation TestingTestClass
@synthesize mockMailComposeViewController;
+ (id)mailComposeViewController {
return mockMailComposeViewController;
}
@end
Run Code Online (Sandbox Code Playgroud)
现在我们已准备好进行测试了.我做了一些不同的事情:
这是测试:
- (void) testEmail {
TestClass *testInstance = [[[TestClass alloc] init] autorelease];
id mock = [OCMockObject mockForClass:[MFMailComposeViewController class]];
[[mock expect] setSubject:@"Test Message"];
[testInstance setMockMailComposeViewController:mock];
[testInstance testMethod];
[mock verify];
}
Run Code Online (Sandbox Code Playgroud)
为了完整性,我们需要一个最终测试,这是为了保证实际类中的工厂方法返回我们期望的:
- (void)testMailComposerViewControllerShouldBeCorrectType {
STAssertTrue([[TestClass mailComposeViewController]
isKindOfClass:[MFMailComposeViewController class]], nil);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3169 次 |
| 最近记录: |