OCMock test if method does nothing but is called - objective-c

Using OCMock, how do I test if a method does nothing?
- (void)myMethod:(BOOL)active
{
if (active) {
// Set property or do whatever
}
// Do nothing -- I need to test this scenario
}

You can create a partial mock to verify that the method is called. Then you have to devise a test that makes sure that the code inside the if statement isn't reached. How to do that depends entirely one what "// Set property or do whatever" does.
That said, if you have an if statement around the entire body of your method you might want to consider refactoring your code...

Related

How to mock a constructor with a spy?

I am currently trying to test my Exposed Kotlin code. I have a table that follows the form
object Foo: Table() {
*parameters*
}
and a method that looks something like
fun addNewFoo(){
Foo.insert { ... }
}
I'm testing addNewFoo and I want to verify the insert occurred, ideally using something like
verify { FooSpy.insert { ... } }
How do I mock the Foo table to be a spy so I can verify the call occurred, or what other approach should I take to verify this method being called?
You can first mock your singleton Foo class using mockkObject() and then verify. Here is the code:
mockkObject(Foo) // mock the object
addNewFoo() // call function that we're testing
verify { Foo.insert(any()) } // verify
There is discussion of ways to go about it: https://github.com/JetBrains/Exposed/issues/317
There seems to be no real intended way for testing but making small test tables in a test data base is the closest you can get.

Using public and private methods inside their class in Perl 6

If I have a public method, I can call it inside its class using both $.name and self.name:
class TEST {
has Int $.a;
method b($x) {
return $!a * $x;
}
method c($y) {
return self.b($y) * 3; # or $.b($y)
}
}
my $m = TEST.new(a => 10);
say $m.c(2); # 60
But if I make b a private method, I only can call it with self!b, not $!b, otherwise I get the following error message:
Attribute $!b not declared in class TEST
What's behind this rule? What are the rules of calling a method inside its own class?
An attribute can always be referred to as $!foo in a class. If you do that, than the code will be generated to directly access the attribute itself, and any classes subclassing your class will not be able to change this behaviour.
If you use has $.foo in the declaration of a class, it means that a public accessor (and if you add is rw it can also function as a mutator).
When you use $.foo in your code otherwise, it is exactly the same as $( self.foo ). This means that it will call the method foo on self, and itemize the return value (make it a single "thing" if it wasn't yet). This will go wrong if you defined your attribute with $!foo and you did not supply a method foo yourself.
This goes even further: $.bar really means self.bar: you only need to have a method existing by the name bar, which may not be related to any attribute at all.
If you define a private method !baz, the ! just indicates the privacy of the method, which means you need to call it indeed as self!baz. There is no short syntax for it.
Personally I dislike the fact that you can say $.zippo even if zippo is not an attribute. But I'm afraid that ship has sailed. But this behaviour is now causing you confusion :-(
So what's behind the rule for not having a short syntax for calling a private method? Not sure, I guess really that $!foo was already taken to mean direct access to the attribute, and provide you with a compile time error if the attribute doesn't exist.
Hope this answers your question!

Object argument to mock EXPECT_CALL

I have a simple mock class:
class MockCanInterface : public lib::CanInterface {
public:
MockCanInterface() : CanInterface({"mock"}) {}
MOCK_METHOD1(Write, bool(const lib::CanFrame& frame));
MOCK_METHOD1(Read, bool(lib::CanFrame* frame));
};
In the test code I want to pass an object to the Write method. Is there a way to do this with .With clause? It works with passing argument directly, but now with .With. The code compiles, but fails during execution - the size of the object is correct, but the data isn't.
This works:
EXPECT_CALL(can_, Write(expected_command_))
.WillOnce(Return(true));
This doesn't:
EXPECT_CALL(can_, Write(_))
.With(Args<0>(expected_command_))
.WillOnce(Return(true));
I admit that there may be something missing in the way the code sets the expected object.
I think the point is: The method Write() required a CanFrame argument passed by reference.
I suggest to use the Actions provided by GMock:
SetArgReferee - reference or value
SetArgPointee - pointer
You can find examples and much more here
However this solution works for me, I hope for you too ;)
EXPECT_CALL(can_, Write(_))
.WillOnce(SetArgReferee<0>(expected_command_));
or with the return value:
EXPECT_CALL(can_, Write(_))
.WillOnce(DoAll(SetArgReferee<0>(expected_command_), Return(true)));

Specifying method's behaviour via EXPECT_CALL vs in body

From what I understand gmock (and I'm new to it) EXPECT_CALL allows for specifying how a method will behave when it's called (in this case I'm mostly interested in what it will return). But I could just as well define the method explicitly with its body. Example:
class Factory
{
int createSomething();
};
class MockFactory : public Factory
{
MOCK_METHOD0(createSomething, int());
};
int main()
{
...
int something(5);
MockFactory mockFactory;
EXPECT_CALL(mockFactory, createSomething()).WillRepeatedly(Return(something));
...
}
vs
class MockFactory : public Factory
{
int createSomething()
{
return 5;
}
};
Now, if createSomething were to behave differently (return different things) in different scenarios then obviously I should use EXPECT_CALL. But if it's going to always return the same thing wouldn't it be better to just explicitly define the method's body? (Note that other methods in the mocked class might still use EXPECT_CALL.)
When you define a method you miss all the flexibility that mocking that method can give you in the tests.
If you need to assert in a test that createSomething gets called, you can only do it if you have mocked it, not if you have a standard method definition. Not in this case, but in case of methods taking parameters, it's even better to have a mock.
If you need to set up a default action that your method should perform, even when you don't set any expectations on it, do so using ON_CALL macro in the SetUp member function of a TestFixture.

Mocking Objective-C code in Swift Unit-Tests

NOTE: This isn't my actual code, I re-typed it in a simple fashion on to here for your help.
I have this class written in Objective-C
#interface MySpecialManager <NSObject>
+ (MySpecialManager *)sharedInstance;
-(void)someFunctionWithParamOne:(NSString *)paramOne andParamTwo:(NSString *)paramTwo;
-(void)someFunctionWithParamOne:(NSString *)paramOne andParamTwo:(NSString *)paramTwo success:(void (^)(NSString *))success failure:(void (^)(NSError *error))failure;
#end
I have unit tests (in Swift) for the second function with the success/failure blocks but I am now trying to write unit tests for the first function. All this function does is call the second function. Therefore, I was thinking the best way to test this would be to just check that the second function does indeed get called and with the correct parameters. Therefore, I thought mocking/stubbing was the way to go forward but I am struggling to understand how exactly to unit test this.
From much Googling I read that creating my own Mock object would be the way to go forward so I have this now (written in Swift):
class MockMySpecialManager: NSObject, MySpecialManagerProtocol {
var functionOneWasCalled = false
var functionTwoWasCalled = false
func someFunctionWithParamOne(paramOne: String!, andParamTwo paramTwo: String!) {
functionOneWasCalled = true
}
func someFunctionWithParamOne(paramOne: String!, andParamTwo paramTwo: String!, success: ((String!) -> Void)!, failure: ((NSError!) -> Void)!) {
functionTwoWasCalled = true
}
If in my test though I initialise a MockMySpecialManager and call the first method, it won't call the second one as it just updates the boolean, correct? I could update the mock function to call the second but that feels like cheating and not a real unit test as its not testing my code. How can I test this?
I somehow (or so I think) need to set the manager to MySpecialManager.sharedInstace(), call the first method and then check if my second method was called on the mock.
Any help? What am I misunderstanding/where am I going wrong?
Your current MOC class is actually a complete replacement of the target class, so you aren't actually testing it at all.
If your MOC was a subclass of the target class instead, and only implemented the second method, then the test can call the first method and the MOC can verify that the second method was called.
Often you would use a mocking library to assist with this, and those libraries allow you different ways to do the same thing as above.
Alternatively you wouldn't MOC the target class, you would MOC all of its dependencies. Then your test checks that the dependencies are called appropriately and with the requisite parameters. Then your first and second method tests are the same setup but with slightly different expectations.