jeremy warne
Tengo un objeto simulado en una prueba. El objeto real, PageRepository, implementa un método mágico usando __call(), por lo que si llama a $pageRepository->findOneByXXXX($value_of_field_XXXX), buscará en la base de datos registros que coincidan con ese parámetro.
¿Hay alguna manera de burlarse de ese método?
La llamada al método real se vería así:
$homepage = $pageRepository->findOneBySlug('homepage');
La prueba se vería así:
$mockPageRepository->expects($this->any())
->method('findOneBySlug')
->will($this->returnValue(new Page()));
Pero no funciona: PHPUnit no detecta la llamada al método. La única forma de hacer que vea el método es definir el método explícitamente en PageRepository.
Juan Planitud
Unidad de PHP getMock()
toma un segundo argumento, una matriz con los nombres de los métodos que se burlarán. Si incluye un nombre de método en esta matriz, el objeto simulado contendrá un método con ese nombre, que expects()
y amigos trabajarán en.
Esto se aplica incluso a los métodos que no están definidos en la clase “real”, por lo que algo como lo siguiente debería funcionar:
$mockPageRepository = $this->getMock('PageRepository', array('findOneBySlug'));
Tenga en cuenta que deberá incluir explícitamente cualquier otro método que también deba simularse, ya que solamente los métodos nombrados en la matriz se definen para el objeto simulado.
-
Tenga en cuenta que, si necesita hacer cosas complejas a través de un constructor simulado (por ejemplo, deshabilitar el constructor original), entonces debe llamar
setMethods()
explícitamente por ejemplo$this->getMockBuilder('ClassName')->setMethods(['findById'])->getMock();
porquegetMock()
sobre el constructor no acepta argumentos.– JP
4 de julio de 2016 a las 12:55
Encontré una mejor manera de hacer esto. Todavía no es perfecto, pero no tiene que especificar todos los métodos de clase de burla a mano, solo métodos mágicos:
$methods = get_class_methods(PageRepository::class);
$methods[] = 'findOneBySlug';
$pageRepositoryMock = $this->getMockBuilder(PageRepository::class)
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->disallowMockingUnknownTypes()
->setMethods($methods)
->getMock();