- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我无法编译这段代码:
[verify(mockedContext) deleteObject:item1];
[verify(mockedContext) deleteObject:item2];
[verify(mockedContext) save:anything()];<--compilation error for conversion id to NSError**
但是,在类似情况下,我可以使用具有附加语法的 given
宏通过编译:
[[given([mockedContext save:nil]) withMatcher:anything()] willReturn:nil];
有什么可以帮助我通过验证的编译吗?
这里是编译错误:
Implicit conversion of an Objective-C pointer to 'NSError *__autoreleasing *' is disallowed with ARC
最佳答案
我假设“mockedContext”上的 save:
方法采用指向 NSError 的指针。
所以实际上,NSError 必须被视为save:
方法的额外返回值。这意味着您应该首先设定一个期望值。
我做了一个小例子:
我们从 Context 协议(protocol)开始,使用一个简单的方法接受 NSError**
。
@protocol Context <NSObject>
- (id)doWithError:(NSError *__autoreleasing *)err;
@end
接下来是一个使用此协议(protocol)的类,很像您的 SUT。我称它为 ContextUsingClass
@interface ContextUsingClass : NSObject
@property (nonatomic, strong) id<Context> context;
@property BOOL recordedError;
- (void)call;
@end
@implementation ContextUsingClass
- (void)call {
NSError *error;
[self.context doWithError:&error];
if (error) {
self.recordedError = YES;
}
}
@end
如您所见,当上下文方法 doWithError:
返回错误时,recordedError 属性设置为 YES。这是我们可以预期在我们的测试中是对还是错的东西。唯一的问题是,我们如何告诉 mock 导致错误(或成功而没有错误)?
答案相当简单,几乎是您问题的一部分:我们将 OCHamcrest 匹配器传递给 given
语句,这反过来会设置错误我们穿过一个街区。耐心等待,我们会到达那里。让我们首先编写拟合匹配器:
typedef void(^ErrorSettingBlock)(NSError **item);
@interface ErrorSettingBlockMatcher : HCBaseMatcher
@property (nonatomic, strong) ErrorSettingBlock errorSettingBlock;
@end
@implementation ErrorSettingBlockMatcher
- (BOOL)matches:(id)item {
if (self.errorSettingBlock) {
self.errorSettingBlock((NSError * __autoreleasing *)[item pointerValue]);
}
return YES;
}
@end
如果已设置此匹配器,它将调用 errorSettingBlock
,并且将始终返回 YES,因为它接受所有项目。匹配器的唯一目的是在测试要求时设置错误。来自 OCMockito issue 22它是 fix ,我们了解到指向指针的指针被包装在 NSValue
对象中,所以我们应该打开它,并将其转换为我们众所周知的 NSError **
最后,测试结果如下:
@implementation StackOverFlowAnswersTests {
id<Context> context;
ContextUsingClass *sut;
ErrorSettingBlockMatcher *matcher;
}
- (void)setUp {
[super setUp];
context = mockProtocol(@protocol(Context));
sut = [[ContextUsingClass alloc] init];
sut.context = context;
matcher = [[ErrorSettingBlockMatcher alloc] init];
}
- (void)testContextResultsInError {
matcher.errorSettingBlock = ^(NSError **error) {
*error = [NSError errorWithDomain:@"dom" code:-100 userInfo:@{}];
};
[[given([context doWithError:nil]) withMatcher:matcher] willReturn:nil];
[sut call];
assertThatBool(sut.recordedError, is(equalToBool(YES)));
}
- (void)testContextResultsInSuccess {
[[given([context doWithError:nil]) withMatcher:matcher] willReturn:nil];
[sut call];
assertThatBool(sut.recordedError, is(equalToBool(NO)));
}
@end
当您在 SUT 中调用通过指针到指针返回错误的方法时,您可能应该测试不同的可能结果,而不是仅仅验证该方法是否已被调用。
如果你的 SUT 忽略了这个错误,那么让你传递给匹配器的 block 保留一个 bool 标志来指示它是这样调用的:
- (void)testNotCaringAboutTheError {
__block BOOL called = NO;
matcher.errorSettingBlock = ^(NSError **error) {
called = YES;
};
[[given([context doWithError:nil]) withMatcher:matcher] willReturn:nil];
[sut call];
assertThatBool(called, is(equalToBool(YES)));
}
或者通过简单的验证:
- (void)testWithVerifyOnly {
[sut call];
[[verify(context) withMatcher:matcher] doWithError:nil];
}
PS:忽略错误可能是您不想做的事情...
关于ios - OCMockito 验证和 NSError 的编译错误**,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23808124/
如何使用 OCMockito 捕获具有原始值的参数? MKTArgumentCaptor 似乎只能捕获对象类型? Xcode 说“不兼容的整数转换指针”。 最佳答案 对于原始论点,您必须跳一些舞。假设
如何获取模拟对象的调用次数? 在测试的某个特定点,我想获取某个方法的当前调用计数,然后继续测试并最终验证该方法是否被再次调用。 这会是这样的: [given([mockA interestingMet
首先我模拟了一个对象。然后我做了一些应该调用对象的特定方法的事情。调用是异步的。 所以我想验证的是:最多5秒后,应该调用mock对象的这个方法。 有什么想法吗? 最佳答案 OCMockito 不支持异
我正在尝试验证模拟对象上的函数是否根本没有使用任何参数调用。 我正在模拟的对象的函数是... - (void)registerUserWithUsername:(NSString*)username
在使用 OCMockito 时,以下效果很好: DSAPIManager *mockAPIManager = mock([DSAPIManager class]); [given([mockAPIMa
我有一个具有只读属性的类。 typedef NS_ENUM(NSInteger, MyObjectStates) { MyObjectStatesUnknown, MyObjectStat
我使用 OCMock 对类 lvl 方法进行 stub ,效果很好。现在我需要使用 OCMockito 实现相同的行为。 在 OCMock 中我有以下内容: _mock = mockClass([My
我在 ClassA 中有这两个方法 -(IBAction)onSubmit; -(void)validateName:(NSString*)name; @实现 - (IBAction)onSubmit
我有一个 View Controller ,它在 viewDidLoad 期间将自己添加为 UIApplicationDidBecomeActiveNotification 的观察者。我想验证是否发生
我正在尝试测试基于 Storyboard的应用程序。该场景是一个导航 Controller ,里面有一个 View Controller 。测试是执行 segue 将 View Controller
这是我的单元测试的伪代码: int invocationCount given(mock).willDo { invocationCount++ return value } doSo
我无法编译这段代码: [verify(mockedContext) deleteObject:item1]; [verify(mockedContext) deleteObject:item2]; [
方法签名: - (void)updateFeaturesButtons:(NSInteger)gameId category:(FeatruesCategory)ca
OCMockito documentation claims it's possible to mock class objects ,但如果我能弄清楚怎么做,我该死。以下测试因 Expected "
对于 iOS tdd 测试/模拟,您会推荐哪个框架?我听说 OcMock 存在时间更长,而且更轻量级。任何人都可以提供一些优缺点的例子或演示每个的一些优点。我只是在寻找一个快速的标准模拟框架,但我想知
对于方法签名 - (void)insertValue:(NSUInteger)value; 我正在尝试查看是否永远不会调用任何值的 insertValue。 [verifyCount(test, ne
我想用以下消息声明模拟一个对象: - (void)createWithCompletion:(void (^)(FuseResult *result, NSError *err)) 完成; 是否可以模
我有一个类 QuestionBuilder 的 OCMockito 模拟,方法是 questionsFromJSON:error:。此方法接受句柄 (NSError **)error 作为参数。如何验
我正在尝试使用 OCMockito 来 stub NSJSONSerialization 方法。我以为我有一个解决方案,但事实证明它会导致此异常: *** -[__NSArrayM objectAtI
我在 Xcode 5 上使用 Cocoapods 设置 OCMockito(和 OCHamcrest)时遇到问题。这是我的 Podfile: platform :ios, '5.0' pod 'Res
我是一名优秀的程序员,十分优秀!