I tried the documentation: http://ocmock.org/reference/#argument-constraints and I can't make work to return any value different of 0
My code is working with:
OCMStub([self.mockCurrentUser tipOptionSelected]).andReturn(0);
How can I do something like:
OCMStub([self.mockCurrentUser tipOptionSelected]).andReturn(OCMOCK_VALUE([OCMArg isNotEqual:0]);
I want to that my stub return any Int except 0.
Thanks
It feels like you misunderstood something. A stub (by definition) has to return a predefined value. The return value is programmed behaviour of the stub. The matching occurs on the arguments to determine whether the stub matches the invocation. This is also why they are called argument constraints.
Related
I have a method:
-(void)startTaskForResult:(long long*)result {
...
}
The function I want to unit test invoke above function:
-(void)doWork {
long long result = 0;
[self startTaskForResult:&result];
}
I am using OCMock library to do unit tests. In my test case, I want to set the result argument to an mocked value e.g. 100 without care about the actual implementation of -(void)startTaskForResult:(long long*)result.
I tried the following way:
-(void)testDoWork{
// try to set 100 to argument 'result'
OCMStub([classToTest startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]);
// run the function, but it doesn't use mocked value 100 for argument 'result'
[classToTest doWork];
...
}
But, when I run my test, it does't use the mocked value 100 for argument result. What is the right way to set mocked value to argument in my case then?
Few points to answer your question:
Code for your problem:
- (void)testDoWork
{
id mock = OCMPartialMock(classToTest)
OCMStub([mock startTaskForResult:[OCMArg setToValue:OCMOCK_VALUE((long long){100})]]).andForwardToRealObject;
// set your expectation here
[classToTest doWork];
}
To solve your particular problem:
Your object should be partial mock
Your method should be stubbed (you did it)
Your stub should be forwarded to real object (i assume you need method startTaskForResult: implementation to be called)
However, you face the problems because you are using wrong approach to test;
There're 3 most common strategies to write unit tests:
Arrange-Act-Assert used to test methods
Given-When-Then used to test functions
Setup-Record-Verify used to test side effects. This usually requires mocking.
So:
If you want to test that startTaskForResult: returns particular value - you should call just that and expect return value (not your case, method return type is void)
If method changes the state of object - you should expect that state change, like property value or so
If calling of doWork has a side effect of calling startTaskForResult:, you should stub it and expect it's call, almost like i've written in code above. However (!!!), however you shouldn't expect things like this. This is not a kind of behaviour that has much sense to test, because it's internal class implementation details. One possible case, when both methods are public and it's explicitly stated in class contract, that one method should call another with some preliminary setup. In this case you expect method call with some state / arguments.
To have your application code testable, you require continuously refactoring your code. Some code is untestable, it's probably better to adopt application code rather then try to cover it with tests anyway. You lose the initial goal of tests - refactoring safety and low cost of making changes.
I'm trying to setup a mock function that will return a value which is based on the input. The only way to access the input parameter that I know of is via the WillExecute method. However, you have to specify a When clause, and that When clause expects me to define an input value along with the method, in the following fashion:
aMock.Setup.WillExecute(function ...).When.myFunc(1);
I'm kinda forced to say: call that anonymous function, whenever myFunc(1) is called. I'd like to be able to do the same, but on every possible parameter to myFunc, with a kind of wildcard marker in the parameter to myFunc (conceptually):
aMock.Setup.WillExecute(function ...).When.myFunc(*);
Is something like this possible? Basically a When clause that will match any value passed as parameter.
Someone might be tempted to point out the WillReturnDefault value, but method does not have access to the actual parameters of the call, as WillExecute does, so I won't be able to setup anything but a constant value.
Thanks.
Ok, I missed the fact that there was an overloaded version of WillExecute that will do exactly that:
//Will exedute the func when called with the specified parameters
function WillExecute(const func : TExecuteFunc) : IWhen<T>;overload;
//will always execute the func no matter what parameters are specified.
procedure WillExecute(const AMethodName : string; const func : TExecuteFunc);overload;
This way I can tell the mock to execute the passed anon whenever the method is called, regardless of its parameters, while still providing access to them. Exactly what I was looking for. Closing question. Thanks.
This can also be solved by using parameter matching:
aMock.Setup.WillExecute(function ...).When.myFunc(It0.IsAny<Integer>);
I am wondering about the difference in behaviour between using the return statement and defining a function with the pattern foo() = Expression
It's my understanding from: Funtions that a function body can be = Expression and return takes either nothing or an Expression
The reason I am asking is that by my understanding of the documentation the following shouldn't work:
map[int,int] foo(map[int,int] env) = env[0] = 1;
Which it doesn't (causing a parse error) since assignment is a Statement. However, if I slightly modify this function:
map[int,int] foo(map[int,int] env) { return env[0] = 1; }
This seems to work. I am confused because I though return should only take expressions. Also, it looks like from playing around on the REPL this assignment returns a Value so it would be nice be able to define functions that assign and return the modified map.
Maybe I am missing something here though.
Your understanding is fine. The return statement has some extra flexibility though to allow returning the value produced by selected statement kinds such as 'for' and assignment apparently too. See the syntax definition of the return statement in the Rascal grammar here
In future versions we may remove all restrictions and allow statements everywhere.
Taking the below method as an example:
-(void)myMethodName:(int)xCoordinate yCoordinate:(int)yCoordinate
When I write the method in my code [self etc...], Xcode does its auto complete which tells me what the second value is for but never the first (see pic).
Is there any way I can also include the 'description' for the first value of a method?
This is just a matter of how you name your method. It autocompletes the entire method name. If the method name is descriptive of its parameters, then you'll see it in the autocomplete.
Are you trying to get something like this?
-(void)myMethodNameWithXCoordinate:(int)xCoordinate yCoordinate:(int)yCoordinate
This is how the methods are usually defined in objective C
- (int)addX:(int)x toY:(int)y {
int sum = x + y;
return sum;
}
Like others have said rename your method this way and it will make things clearer
-(void)moveStuffFromXCoordinate:(int)xCoordinate toYCoordinate:(int)yCoordinate
Based on the Apple Documentation on coding guidelines for cocoa when naming methods with parameters the word before the argument should describe the argument.
Make the word before the argument describe the argument.
Right - (id)viewWithTag:(NSInteger)aTag;
The above is right because it describes the argument as a Tag where as the below doesn't describe the argument as anything.
Wrong - (id)taggedView:(int)aTag;
So in your case
Wrong -(void)myMethodName:(int)xCoordinate yCoordinate:(int)yCoordinate;
it should be
Right -(void)myMethodNameForXCoordinates:(int)xCoordinate andYCoordinate:(int)yCoordinate;
I have some code that wants to do grab some extra return values from a function and pass them forward latter on:
local ok, ... = coroutine.resume(co)
do_stuff(ok)
return ...
However, this won't run since the ... on the variable assignment is a syntax error.
I could work around this limitation by using the old "functions arguments and variables are equivalent" trick and an immediately-invoked function
return (function(ok, ...)
do_stuff(ok)
return ...
)(coroutine.resume(co))
but I imagine doing so wouldn't be very idiomatic or efficient. Are there more reasonable ways to solve this problem of handling the remaining values returned from the resume call?
EDIT: By the way, this needs to work with nil values in the extra arguments
EDIT2: Looks like using the immediately invoked function was the best way all along.
IMHO, the best way is passing vararg as parameter to helper function as you have done in your question.
The alternative way is "pack-unpack":
-- Lua 5.2 only
local t = table.pack(coroutine.resume(co))
do_stuff(t[1])
return table.unpack(t, 2, t.n)
The idiomatic way to do this with an unknown number of return values is to wrap the function call in a table constructor:
local t = { coroutine.resume(co) }
do_stuff(table.remove(t, 1))
return unpack(t) -- table.unpack(t) in lua 5.2
While this also involves creating a temporary object, it should be a lot quicker than using a closure, and it's certainly a lot neater.