gpt4 book ai didi

ios - 将 OCMock 与未知数量的方法调用一起使用

转载 作者:行者123 更新时间:2023-11-29 10:59:47 24 4
gpt4 key购买 nike

我将 OCMock 与 GHUnit 结合使用,尝试从测试驱动的 iOS 开发中重新创建 Graham Lee 的“BrowseOverflow”项目。

我的理解是模拟任何不是来自您正在测试的当前类的对象。我正在使用我的 Question 类,它依赖于我的 Answer 类的某些功能。

问题.h

@class Answer;

@interface Question : NSObject {
NSMutableSet *answerSet;
}

@property (retain) NSDate *date;
@property NSInteger score;
@property (copy) NSString *title;
@property (readonly) NSArray *answers;

- (void)addAnswer:(Answer *)answer;

@end

问题.m

#import "Question.h"
#import "Answer.h"

@implementation Question

@synthesize date;
@synthesize score;
@synthesize title;

- (id)init
{
if ((self = [super init])) {
answerSet = [[NSMutableSet alloc] init];
}
return self;
}

- (void)addAnswer:(Answer *)answer
{
[answerSet addObject:answer];
}

- (NSArray *)answers
{
return [[answerSet allObjects] sortedArrayUsingSelector:@selector(compare:)];
}

@end

Answer.h

#import <Foundation/Foundation.h>

@class Person;

@interface Answer : NSObject

@property (readwrite) NSString *text;
@property (readwrite) Person *person;
@property (readwrite) NSInteger score;
@property (readwrite, getter = isAccepted) BOOL accepted;

- (NSComparisonResult)compare:(Answer *)otherAnswer;

@end

Answer.m

#import "Answer.h"

@implementation Answer

@synthesize text;
@synthesize person;
@synthesize score;
@synthesize accepted;

- (NSComparisonResult)compare:(Answer *)otherAnswer
{
if (accepted && !(otherAnswer.accepted)) {
return NSOrderedAscending;
} else if (!accepted && otherAnswer.accepted) {
return NSOrderedDescending;
}
if (score > otherAnswer.score) {
return NSOrderedAscending;
} else if (score < otherAnswer.score) {
return NSOrderedDescending;
}
return NSOrderedSame;
}

@end

我在测试时尝试使用 OCMock 来替代 Answer 的实例,但它只在大约 10% 的时间内起作用。

- (void)testHighScoreAnswerBeforeLow
{
lowScore = [OCMockObject mockForClass:[Answer class]];
[[[lowScore stub] andReturn:OCMOCK_VALUE((NSInteger) {4})] score];
[question addAnswer:lowScore];

highScore = [OCMockObject mockForClass:[Answer class]];
[[[highScore stub] andReturn:OCMOCK_VALUE((NSInteger) {-4})] score];
[question addAnswer:highScore];

[[lowScore expect] compare:[OCMArg any]];

NSArray *answers = question.answers;
NSInteger highIndex = [answers indexOfObject:highScore];
NSInteger lowIndex = [answers indexOfObject:lowScore];
GHAssertTrue(highIndex < lowIndex, @"High-scoring index comes first");

[highScore verify];
[lowScore verify];
}

我认为问题是由 NSSet 在内存中存储对象的方式(有点随机)和 OCMock 检查以确保没有调用额外方法这一事实引起的冲突。我通过将 OCMock 从这个特定测试中移除来解决,但这似乎是一个糟糕的测试。

- (void)testHighScoreAnswerBeforeLow
{
lowScore = [[Answer alloc] init];
lowScore.score = -4;
[question addAnswer:lowScore];

highScore = [[Answer alloc] init];
highScore.score = 4;
[question addAnswer:highScore];

NSArray *answers = question.answers;
NSInteger highIndex = [answers indexOfObject:highScore];
NSInteger lowIndex = [answers indexOfObject:lowScore];
GHAssertTrue(highIndex < lowIndex, @"High-scoring index comes first");
}

当您不知道需要进行多少次比较时,是否可以让 OCMock 很好地处理排序算法?如果不是,这是使用 OCMock 的缺点还是结构不良的代码?

最佳答案

问题在于您对比较设置了期望。如果您不关心它被调用了多少次,则不应告诉模拟您希望它被调用一次。

如果您不关心在模拟对象上调用了哪些意外方法,您可以使用 nicemock。

您可以使用 stub 来只返回某个值而不关心它被调用了多少次。

关于ios - 将 OCMock 与未知数量的方法调用一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16446551/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com