in unit test, set mocked value to an argument (pass-by-reference) - ios

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.

Related

OCMClassMock and OCMStrictClassMock

I am new in OCMock 3, I see there are two methods:
OCMClassMock(cls): creates a new nice class mock object
OCMStrictClassMock(cls): creates a class mock object
I read the document, but I feel still confused & have two questions:
What exactly the difference between OCMClassMock(cls) and OCMStrictClassMock(cls) ?
When should I use OCMClassMock(cls) and when should I use OCMStrictClassMock(cls)?
====UPDATE====
Can I understand as OCMClassMock(cls) is partial mock that the real implementation still run when call method on it and OCMStrictClassMock(cls) is a full mock like a skeleton without real implementation?
Can I understand as OCMClassMock(cls) is partial mock that the real
implementation still run when call method on it
This describes OCMPartialMock.
OCMStrictClassMock(cls) is a full mock like a skeleton without real
implementation?
This is an accurate general description of OCMClassMock.
From the reference you linked:
[OCMStrictClassMock] Creates a mock object in strict mode. By
default mocks are nice, they return nil (or the correct default value
for the return type) for whatever method is called. In contrast,
strict mocks raise an exception when they receive a method that was
not explicitly expected.
So as you said, OCMClassMock is like a skeleton of an instance where you only stub the methods that you need to use. The difference between OCMClassMock and OCMStrictClassMock is that the former will simply return nil for a method that you haven't explicitly stubbed, whereas the latter will throw an exception if you call a method on it that you haven't explicitly stubbed.

How can Cmocka test that my (void) callback function was called with the correct parameters?

I am using Cmocka for unit test and that cannot be changed.
I am testing part of my software which invokes callback functions, if a value changes, indicating which data item changed and what the new value is.
The callback functions have this signature:
typedef void (* Value_changed_call_back) (int item_Id, int new_value);
For unit test, I want to register some callback functions and ensure that they are actually invoked, and that they receive the correct parameters.
I can use expect_int() in my mocks, to validate that they are invoked with the correct parameters.
But, I don't see how I can use will_return() since my call back functions are of type void (and that can't be changed).
How would I declare a mock callback function and verify that it is called with the correct parameters? Note that if the function is not called, then the test should fail.
I saw this post and thought about this in CMocka API.
You can use expect_function_call(func) to indicates which function should be called and function_called() in the callback to mark the function as called.
I'm not sure since how long this feature is available (but present in 1.1.5 version).
I answered to this question in case someone comes across this topic even if it's a 2016 ask.
I think the best way to do what you want is to create a stub for the callback and register that. Then inside the callback you set some global variable to a value. Then you would be able to assert that value that gets set in your stub function. This works so long as the assert and the callback are executed on the same thread to make sure that the assert is not a race condition.

Understanding Mock Unit Testing

am trying to understand using Mock unit testing and i started with MOQ . this question can be answered in General as well.
Am just trying to reuse the code given in How to setup a simple Unit Test with Moq?
[TestInitialize]
public void TestInit() {
//Arrange.
List<string> theList = new List<string>();
theList.Add("test3");
theList.Add("test1");
theList.Add("test2");
_mockRepository = new Mock<IRepository>();
//The line below returns a null reference...
_mockRepository.Setup(s => s.list()).Returns(theList);
_service = new Service(_mockRepository.Object);
}
[TestMethod]
public void my_test()
{
//Act.
var myList = _service.AllItems();
Assert.IsNotNull(myList, "myList is null.");
//Assert.
Assert.AreEqual(3, myList.Count());
}
Here is my question
1 . In testInitialize we are setting theList count to 3(string) and we are returning the same using MOQ and in the below line we are going to get the same
var myList = _service.AllItems(); //Which we know will return 3
So what we are testing here ?
2 . what are the possible scenarios where the Unit Testing fails ? yes we can give wrong values as 4 and fail the test. But in realtime i dont see any possiblity of failing ?
i guess am little backward in understanding these concepts. I do understand the code but am trying to get the insights !! Hope somebody can help me !
The system under test (SUT) in your example is the Service class. Naturally, the field _service uses the true implementation and not a mock. The method tested here is AllItems, do not confuse with the list() method of IRepository. This latter interface is a dependency of your SUT Service therefore it is mocked and passed to the Service class via constructor. I think you are confused by the fact that AllItems method seems to only return the call from list() method of its dependency IRepository. Hence, there is not a lot of logic involved there. Maybe, reconsider this example and add more expected logic for the AllItems method. For example you may assert that the AllItems returns the same elements provided by the list() method but reordered.
I hope I can help you with this one.
1.) As for this one, your basically testing he count. Sometimes in a collection, the data accumulates so it doesn't necessarily mean that each time you exectue the code is always 3. The next time you run, it adds 3 so it becomes 6 then 9 and so on.
2.) For unit testing, there are a lot of ways to fail like wrong computations, arithmetic overflow errors and such. Here's a good article.
The test is supposed to verify that the Service talks to its Repository correctly. We do this by setting up the mock Repository to return a canned answer that is easy to verify. However, with the test as it is now :
Service could perfectly return any list of 3 made-up strings without communicating with the Repository and the test would still pass. Suggestion : use Verify() on the mock to check that list() was really called.
3 is basically a magic number here. Changes to theList could put that number out of sync and break the test. Suggestion : use theList.Count instead of 3. Better : instead of checking the number of elements in the list, verify that AllItems() returns exactly what was passed to it by the Repository. You can use a CollectionAssert for that.
This means getting theList and _mockRepository out of TestInit() to make them accessible in a wider scope or directly inside the TestMethod, which is probably better anyways (not much use having a TestInitialize here).
The test would fail if the Service somehow stopped talking to its Repository, if it stopped returning exactly what the Repository gives it, or if the Repository's contract changed. More importantly, it wouldn't fail if there was a bug in the real implementation for IRepository - testing small units allows you to point your finger at the exact object that is failing and not its neighbors.

Need to mock one service method only in an integration test

I am writing grails integration tests which call out to a controller which call a service which calls another service which calls another service.
Controller -> ServiceA.method1() -> ServiceB.method2() -> ServiceC.method3()
the last method in the last service to be called (ServiceC.method3()) makes a call to the outside world (another JVM) and returns a result, which I want to mock out for my integration test. So I am still testing the chain up to and back from that particular service method.
I was reading up on mocking in grails but it seems that it is only possible in unit testing.
Any tips how to progress this one?
Use the metaClass to override a method's functionality. I do this all the time in my integration tests as my way to mock.
So in your test method do something like this (note that the method arg types must match exactly with the real method):
controller.serviceA.serviceB.serviceC.metaClass.method3 = { Args args ->
// do whatever you want here, set flags to indicate method called,
// assert args, declare return types, etc
// return 'mocked' result
}
Make sure in your integration test tear down method you reset the metaClass of this service otherwise all your other int tests will have the same definition:
controller.serviceA.serviceB.serviceC.metaClass = null
I was reading up on mocking in grails but it seems that it is only
possible in unit testing.
That's certainly not true.
You could use all ways of mocking that are available in Groovy in both unit and integration tests.
With mocking using Map coercion, it can be this easy:
controller.serviceA.serviceB.serviceC = [method3: {return 'MockValue'}] as ServiceC

Verify method call with OCMockito

I have these two methods in a ClassA
-(IBAction)onSubmit;
-(void)validateName:(NSString*)name;
#Implementation
- (IBAction)onSubmit {
[self validateName:self.textfield.text];
}
-(void)validateName:(NSString*)name{
// do something
}
My test look like the below:
//given
ClassA *classA = mock([ClassA class]);
classA.textfield.text = #"Foo";
// when
[classA onSubmit];
[verify(classA) validateName:#"Foo"];
But that doesn't work, I keep getting:
Expected 1 matching invocation, but received 0
How can I write a test that verifies that validateName is executed, when onSubmit is being called.
Proper unit tests test internal state and external behavior. Your unit tests are testing whether your code does something, not how it does something. The state verification tells you that your intended results are achieved, while the behavior verification tells you that your collaborating objects correctly interface with your system under test. This allows you to do wonderful things like refactor.
A test of internal state goes like this:
Given an initial state, if the system under test does something, then
the resultant state should be this.
A test of external behavior goes like this:
If the system under test does something, then another unit should do something else.
The first sort of tests are accomplished with standard assertions (assertThat() calls in the case of OCHamcrest). The second sort of tests are (properly) accomplished with verification of test doubles (verify() calls in the case of OCMockito).
It wouldn’t make any sense to mock the system under test. If you find it necessary to test the internal behavior (i.e. the particular methods called by the system under test), then you need to map those behaviors to states. In your case this would mean that ClassA implements a flag such as BOOL nameValidated (preferably with the getter isNameValidated) or a variable such as NSString *validatedName.

Resources