sirven que para las interfaces clases php unit-testing symfony mocking phpunit

para - ¿Método indefinido en objeto simulado que implementa una interfaz dada en PHPUnit?



clases e interfaces en php (3)

Es porque no hay ninguna declaración del método "getClass" en ConfigurationInterface. La única declaración en esta interfaz es el método "getAliasName".

Todo lo que necesitas es decirle al simulacro de los métodos que estarás tocando:

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

Tenga en cuenta que no hay una declaración "getClass" pero que también puede quitar / simular un método no existente. Por eso puedes burlarte de ello:

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

Pero además, debe simular el método "getAliasName" y el método de la interfaz o uno abstracto, y debe ser "implementado". P.ej.:

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

Soy nuevo en pruebas de unidad y PHPUnit.

Necesito un simulacro, en el que tengo un control total, implementando la interfaz ConfigurationInterface . El sujeto de prueba es el objeto ReportEventParamConverter y la prueba debe verificar la interacción entre mi objeto y la interfaz.

Objeto ReportEventParamConverter (aquí simplificado):

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(); } }

Y esta es la forma en que estoy tratando de burlarme de la interfaz:

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

Necesito simular los valores devueltos para dos métodos: getClass() y getName() . Por ejemplo:

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

Cuando creo un nuevo ReportEventParamConverter y prueba el método supports() , obtengo el siguiente error PHPUnit:

Error grave: llamada a un método no definido Mock_ConfigurationInterface_21e9dccf :: getClass ().

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


La advertencia de Tyler Collier es justa pero no contiene un fragmento de código sobre cómo codificar a su alrededor. Tenga en cuenta que esto es muy desagradable y que debería arreglar la interfaz en su lugar. Con esa advertencia agregada:

$methods = array_map(function (/ReflectionMethod $m) { return $m->getName();}, (new /ReflectionClass($interface))->getMethods()); $methods[] = $missing_method; $mock = $this->getMock($interface, $methods);


La respuesta de Cyprian me ayudó, pero hay un problema que hay que tener en cuenta. Puedes simular clases que no existen, y PHPUnit no se quejará. Para que pudieras hacer

$mock = $this->getMock(''SomeClassThatDoesntExistOrIsMisspelledOrPerhapsYouForgotToRequire'');

Esto significa que si ConfigurationInterface no existe en ese momento durante el tiempo de ejecución, seguirá recibiendo un mensaje como

Error grave: llamada a un método no definido Mock_ConfigurationInterface_21e9dccf :: getClass ().

Si está seguro de que el método realmente existe en la clase, entonces el problema probable es que la clase en sí misma no existe (porque no la ha requerido o está mal escrita, etc.).

El OP está utilizando una interfaz . Tenga en cuenta que debe llamar a getMock sin especificar la lista de métodos para anular, o si lo hace, debe pasar array() o pasar TODOS los nombres de los métodos, o recibirá un error como el siguiente:

Error fatal de PHP: Class Mock_HttpRequest_a7aa9ffd contiene 4 métodos abstractos y, por lo tanto, debe declararse abstracto o implementar los métodos restantes (HttpRequest :: setOption, HttpRequest :: execute, HttpRequest :: getInfo, ...)