4

I'm new to OCMock and had a question.

Can we stub a method of a class, where calling that method over any instance/object of that class gets mocked

For Example : if Class_A has a non static function_a and Class_B has function_b which internally declares a object_o of Class_A.

    Class_A
    {
        - function_a
    }

    Class_B
    {
        - function_b
        {
            Obj_o of Class A
            [Obj_o a];
        }
    }

Now, I want to write unit test for Class_B and test function_b.

Is there some mechanism where I create a mock of Class_A and stub function_b and then run the test function_b and be sure that function_b got stubbed.

I know that if I change the function definition of function_b to have the object_o sent as a parameter, it works. We create an object mock of class_A, stub for function_b, and send that object mock as a parameter to function_b because it gets the reference for the mocked object. But I want to check regarding the feasibility of testing such functions without changing the function definitions. Does OCMock provide such functionality.

2 Answers2

2

If you don't want to change the existing method definitions but are ok with changes to your existing code, you can use this approach:

To create the Obj_o of Class A in function_b use a class method on Class_A, for example newInstance. This method doesn't need to do anything else than the normal [[Class_A] alloc] init]; (change to your init method if you have a custom one). In your test you can that mock this newInstance function to return an instance of your mocked object of Class_B.

See the documentation of OCMock, 9.3 Stubbing methods that create objects.

Nef10
  • 926
  • 2
  • 16
  • 26
  • Thank you for your helpful response. I have checked a similar case for singleton classes: http://stackoverflow.com/questions/37549536/ocmock-automatically-use-mocked-instance-in-code-under-test?rq=1 . However, I wanted to clarify on whether it will not be possible without adding newInstance method which returns back the mocked object. I'm asking the same because I have the entire project with too many classes like Class_A and Class_B and have to refactor everything (like add a new newInstance method to Class_A and change the object declaration in Class_B for each such Class_A and Class_B). – Yashaswi Reddy May 05 '17 at 03:19
1

The following approach should be possible:

  • stub the alloc method on class A
  • in the stub create the instance of class A
  • still in the stubbed method create a partial mock for the instance
  • return that partial mock from the stubbed method

That said, I would recommend to restructure your code to avoid all this trickery.

Erik Doernenburg
  • 2,933
  • 18
  • 21