In a test with OCMock, I must assert that no call is made to the setState: selector. However, I can make no assumption about the other calls that are made to the object.
Because any other call can be made, I have to (or do I?) use a niceMockForClass: instead of mockForClass:
How can I then make sure that no call is made to setState: ?
The code roughly looks like this:
- (void)testNoCallIsMadeToSetStateOnReset
{
self.downloader = [OCMock niceMockForClass:[Downloader class]];
[[self.downloader expectZero] setState:OCMOCK_ANY]; // <- how to do this?
// do some stuff
[self.downloader verify]
}
You can use [[yourMock reject] setState:OCMOCK_ANY];
Related
I'm a newbie in objective c working on swift.io and trying to convert its anonymous callbacks to non-anonymous function.
basically trying to convert
[self.Socket on:#"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
NSLog(#"socket connected");
}];
to something like
[self.Socket on:#"connect" callback:connectTestCallback];
i tried defining a following function which i'll call
- (void) connectTestCallback:(NSArray* )data withAck:(SocketAckEmitter *)ack
{
NSLog(#"socket connected");
}
But i'm not sure if thats how i'm supposed to define it, and have no idea how to call it. I've tried calling it as callback:#selector(connectTestCallback) but obviously that didn't work.
Following is definition of "on" function.
- (void)on:(NSString * __nonnull)event callback:(void (^ __nonnull)(NSArray * __nonnull, SocketAckEmitter * __nonnull))callback;
The "anonymous function" is a block building a closure. In contrast to functions and methods a closure stores its creation environment, so you can access this inside the code. But if the actual arguments are enough data to do what you want to do, you can simply send a message to self to execute the "named" method:
[self.Socket on:#"connect" callback:^(NSArray* data, SocketAckEmitter* ack)
{
[self connectTestCallback:data withAck:ack];
}];
In OCMock there is the method OCMVerify to verify interactions. So I did the following with MyObjectData being a simple value holder class.
OCMVerify([dataStore createOrUpdateMyObject:[OCMArg isKindOfClass:[MyObjectData class]]]);
This works, but is not enough, since I want to verify that the method isn't called with any object of this class but with the correct values. So I did the following:
// ...
OCMVerify([dataStore createOrUpdateMyObject:[OCMArg checkWithSelector:#selector(verifyMyObjectDataAfterSave:) onObject:self]]);
}
- (BOOL)verifyMyObjectDataAfterSave:(id)obj {
return YES;
}
But the obj parameter is not the MyObjectData instance I expect to be passed but an instance of OCMVerifier which is a proxy to the mocked data store.
Now the question is, how can I verify the argument correctly?
Can you use an expectation?
id mockObj = OCMPartialMock(dataStore);
OCMExpect([mockObj createOrUpdateMyObject:[OCMArg checkWithBlock:^BOOL(MyObjectData *value)
{
XCTAssertEqual(value.someProperty, 999);
return [value isKindOfClass:[MyObjectData class]];
}]]);
[mockObj someMethod];
OCMVerifyAll(mockObj);
I have something that looks like the similar specification:
def "my spec"(Record record) {
given:
Something something = getSomething()
and:
otherThing = getOtherThing()
doFlow(something, record)
if (record.someType = Types.SOME_SPECIFIC_TYPE) {
doFlow(something, record)
}
}
def doFlow(Something something, Record record) {
when:
//code
then:
//asserts
when:
//code
and:
//mode code
then:
//code
}
However, at runtime, I get: groovy.lang.MissingMethodException: No signature of method doFlow() is applicable for arguments Something, Record values: [given values].
Both "my flow" and "doFlow" are feature methods as they have blocks such as given, when, and then. It's Spock's responsibility to invoke feature methods, and one feature method cannot call another one. If doFlow is meant to be a helper method, it should use explicit assert statements, and shouldn't have any blocks.
PS: Feature methods can't declare method parameters unless they are data-driven (i.e. have a where block).
PPS: A feature method can't just have a given/and block. (You'll get a compile error for this.)
I use Google Test and Google Mock for making unit tests and there is a need to check calls of object, which was placed into a std::vector. Like this:
TEST(FooTest, someTest)
{
// Given
CSomeClass someObject;
StrictMock<MockFoo> strictFoo;
std::vector<Foo> fooContainer;
fooContainer.push_back(strictFoo);
// Expected
EXPECT_CALL(strictFoo, doSomething()); // can't do this because there is a copy of strictFoo in vector
// When
someObject.do(fooContainer);
}
I'd greatly appreciate any tips on accomplishing this.
I guess I'd go for something more like this:
TEST(FooTest, someTest)
{
// Given
CSomeClass someObject;
std::vector<std::unique_ptr<Foo>> fooContainer;
fooContainer.emplace_back(new MockFoo);
// Expected
auto mock_foo_ptr(static_cast<MockFoo*>(fooContainer.rbegin()->get()));
EXPECT_CALL(*mock_foo_ptr, doSomething());
// When
someObject.Do(fooContainer);
}
I whould like to know if there is a way to determine if performSelector:withObject:afterDelay: for the given object has been called (registered to be called). (I could use cancelPreviousPerformRequestsWithTarget:selector:object: and re-call performSelector:withObject:afterDelay:, ok but I'm interested to know if there is the alternative).
Thanks
The best thing to do would be to make sure that the selector being called can be called multiple times safely.
For example, use a flag in the target object to track if the method has already been invoked e.g.
-targetSelector: (id) param
{
if (!hasBeenRun) // hasBeenRun is a boolean intance variable
{
hasBeenRun = true;
// other stuff
}
}