PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Monday, January 31, 2022

[FIXED] Undefined method on mock object implementing a given interface in PHPUnit?

 January 31, 2022     mocking, php, phpunit, symfony, unit-testing     No comments   

Issue

I'm new to unit testing and PHPUnit.

I need a mock, on which I have a full control, implementing ConfigurationInterface interface. Test subject is ReportEventParamConverter object and test must check the interaction between my object and the interface.

ReportEventParamConverter object (here simplified):

class ReportEventParamConverter implements ParamConverterInterface
{
    /**
     * @param Request $request
     * @param ConfigurationInterface $configuration
     */
    function apply(Request $request, ConfigurationInterface $configuration)
    {
        $request->attributes->set($configuration->getName(), $reportEvent);
    }

    /**
     * @param ConfigurationInterface $configuration
     * @return bool
     */
    function supports(ConfigurationInterface $configuration)
    {
        return 'My\Namespaced\Class' === $configuration->getClass();
    }
}

And this is the way I'm trying to mock the interface:

$cls = 'Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface';
$mock = $this->getMock($mockCls);

I need to simulate the returned values for two methods: getClass() and getName(). For example:

$mock->expects($this->any())
    ->method('getClass')
    ->will($this->returnValue('Some\Other\Class'))
;

When i create a new ReportEventParamConverter and test supports() method, i get the following PHPUnit error:

Fatal error: Call to undefined method Mock_ConfigurationInterface_21e9dccf::getClass().

$converter = new ReportEventParamConverter();
$this->assertFalse($converter->supports($mock));

Solution

It's because there is no declaration of "getClass" method in ConfigurationInterface. The only declaration in this interface is method "getAliasName".

All you need is to tell the mock what methods you will be stubing:

$cls = 'Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface';
$mock = $this->getMock($cls, array('getClass', 'getAliasName'));

Notice that there is no "getClass" declaration but you can stub/mock non existing method as well. Therefor you can mock it:

$mock->expects($this->any())
    ->method('getClass')
    ->will($this->returnValue('Some\Other\Class'));

But in addtion you need to mock "getAliasName" method as well as long as it's interface's method or abstract one and it has to be "implemented". Eg.:

$mock->expects($this->any())
   ->method('getAliasName')
   ->will($this->returnValue('SomeValue'));


Answered By - Cyprian
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home
View mobile version

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing