1

I am trying to learn unit testing. I wrote simple module to get better understanding about mocking. The test should return "Cat" but it return "Dog".

  1. I can not see what is wrong with the code?

  2. In the example code I have two classes, but how should the test be written. When the getVariable method is inside learningMock class? I have read about partialMocking but...

Simplistic\Learning\Model\learningMock:

class learningMock {
    public function __construct(\Simplistic\Learning\Model\learningHelper $learningHelper) {
        $this->_learningHelper=$learningHelper;
    }

 public function learningMethodReplace(){
     $var="Dog";
     if($this->_learningHelper->getVariable()=="Cat"){
         $var="Cat";
     }
     return $var;
 }

Simplistic\Learning\Model\learningHelper.php:

class learningHelper {

 public function getVariable() {
     return "Cat";
 }

Simplistic\Learning\Test\Unit\Model\learningMockTest:

class mockTest extends \PHPUnit_Framework_TestCase {

    public function setUp() {
    $this->learningHelper = $this->getMockBuilder("\Simplistic\Learning\Model\learningHelper")
            ->setMethods(['getVariable'])
            ->disableOriginalConstructor()
            ->getMock();
    $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
    $this->_learningMock = $objectManager->getObject('Simplistic\Learning\Model\learningMock');
}

public function testLearningClassReplace() {
    $this->learningHelper->expects($this->once())
            ->method('getVariable')
            ->will($this->returnValue('Cat'));
    $this->assertEquals('Cat', $this->_learningMock->learningMethodReplace());
  }
}

EDITED: I have manage to get it working, but I do not understand what is happening in the code. Can anyone please explain me, why it is working now (from Magento point of view)?

Simplistic\Learning\Test\Unit\Model\learningMockTest:

use Simplistic\Learning\Model\learningMock;
class mockTest extends \PHPUnit_Framework_TestCase {

    public function setUp() {
    $this->learningHelper = $this->getMockBuilder("\Simplistic\Learning\Model\learningHelper")
            ->setMethods(['getVariable'])
            ->disableOriginalConstructor()
            ->getMock();
    $this->learning = new learningMock($this->learningHelper);
}

public function testLearningClassReplace() {
    $this->learningHelper->expects($this->once())
            ->method('getVariable')
            ->willReturn('Cat');
    $this->assertEquals("Cat", $this->learning->learningMethodReplace());
  }
}
1

You created a mock ($learningHelper), but did not do anything with it.

The object manager contains lots of magic, but not enough to know what you do in your test setup and what's your intention ;-)

Now you passed the mock directly as constructor argument instead of using the object manager, and that's the correct approach in unit tests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.