0

I have a class like this:

<?php
class Apple { 
    public function foo($arg1){
        if ($arg1 == 0){
            $this->bar($arg1);
        }
    }

    public function bar($arg){
        //do something
    }
}

And I have a unit test like this:

class AppleTest extends TestCase{
    /**
     * it's unit test for method Apple::foo
     */
    public function testFoo(){
        $mock = $this->getMockBuilder('Apple')
            ->setMethods(['bar'])
            ->getMock();

        $mock->expects($this->once())
            ->method('bar')
            ->with($this->equalTo(0));

        $mock->foo(0);
    }
}

I was told, that I can't use a mock for the class that is being tested. I was told that I should use instance of the class instead of its mock, because when I use mock it's not actual testing. Can some one argue with that.

Hevyweb
  • 402
  • 1
  • 5
  • 18
  • Mocking is used for external dependencies. Mocking the class you're testing makes no sense since you wouldn't actually be testing anything beyond the unit test code you wrote. – Devon Bessemer Jul 19 '18 at 14:39
  • Possible duplicate of [What is the purpose of mock objects?](https://stackoverflow.com/questions/3622455/what-is-the-purpose-of-mock-objects) – Devon Bessemer Jul 19 '18 at 14:57

1 Answers1

1

It isn't that you "can't", but that you really shouldn't. Obviously from your example test, you can mock the object that you are testing.

But this isn't necessarily a good idea. The issue with this is that you are specifying exactly what the code should look like. This can make refactoring more difficult. Suppose that the bar function needs to change and you want to move the functionality the foo needs into a private function. Now your test will fail because foo is no longer calling bar. In this case, it should pass because the functionality hasn't changed. This is one of the great benefits of unit tests, you are able to refactor the code and ensure that things still work correctly.

However, there are times when it is necessary to mock the class that you are testing. Generally this is when you are trying to write new tests for existing code and you aren't able to refactor it to use dependency injection. Then you will have to mock the other function in order to isolate things. This isn't ideal and should be avoided but writing a "bad" test can be better than having no test at all.

Schleis
  • 41,516
  • 7
  • 68
  • 87