¿Hay alguna forma de definir diferentes simulaciones de espera para diferentes argumentos de entrada? Por ejemplo, tengo una clase de capa de base de datos llamada DB. Esta clase tiene un método llamado "Consulta (cadena $ consulta)", ese método toma una cadena de consulta SQL en la entrada. ¿Puedo crear un simulacro para esta clase (DB) y establecer diferentes valores de retorno para diferentes llamadas al método de consulta que dependen de la cadena de consulta de entrada?
117
Respuestas:
La biblioteca PHPUnit Mocking (por defecto) determina si una expectativa coincide basándose únicamente en el comparador pasado al
expects
parámetro y la restricción pasadamethod
. Debido a esto, dosexpect
llamadas que solo difieren en los argumentos pasadoswith
fallarán porque ambas coincidirán pero solo una verificará que tiene el comportamiento esperado. Vea el caso de reproducción después del ejemplo de trabajo real.Para su problema, debe usar
->at()
o->will($this->returnCallback(
como se describe enanother question on the subject
.Ejemplo:
Reproduce:
Reproduzca por qué dos -> con () llamadas no funcionan:
Resultados en
fuente
$this->anything()
como uno de los parámetros para->logicalOr()
permitirle proporcionar un valor predeterminado para otros argumentos que no sean el que le interesa.No es ideal usarlo
at()
si puede evitarlo porque, como afirman sus documentosDesde 4.1 puede utilizar,
withConsecutive
por ejemplo.Si desea que vuelva en llamadas consecutivas:
fuente
Fatal error: Call to undefined method PHPUnit_Framework_MockObject_Builder_InvocationMocker::withConsecutive()
, actualicé a 4.1 en un instante con Composer y está funcionando.willReturnOnConsecutiveCalls
mató.Por lo que he encontrado, la mejor manera de resolver este problema es utilizando la funcionalidad de mapa de valores de PHPUnit.
Ejemplo de la documentación de PHPUnit :
Esta prueba pasa. Como puedes ver:
Por lo que puedo decir, esta función se introdujo en PHPUnit 3.6 , por lo que es lo suficientemente "antigua" como para que se pueda utilizar de forma segura en prácticamente cualquier entorno de desarrollo o preparación y con cualquier herramienta de integración continua.
fuente
Parece que Mockery ( https://github.com/padraic/mockery ) apoya esto. En mi caso, quiero verificar que se creen 2 índices en una base de datos:
La burla, funciona:
PHPUnit, esto falla:
La burla también tiene una sintaxis mejor en mi humilde opinión. Parece ser un poco más lento que la capacidad de burla incorporada de PHPUnit, pero YMMV.
fuente
Intro
Bien, veo que hay una solución para Mockery, así que como no me gusta Mockery, voy a darte una alternativa de Profecía, pero te sugiero que primero leas sobre la diferencia entre Mockery y Prophecy.
En pocas palabras : "La profecía utiliza un enfoque llamado enlace de mensajes ; significa que el comportamiento del método no cambia con el tiempo, sino que cambia con el otro método".
Código problemático del mundo real para cubrir
Solución PhpUnit Prophecy
Resumen
Una vez más, ¡la profecía es más asombrosa! Mi truco consiste en aprovechar la naturaleza vinculante de mensajería de Prophecy y, aunque lamentablemente parece un código infernal de javascript de devolución de llamada típico, comenzando con $ self = $ this; Como rara vez tienes que escribir pruebas unitarias como esta, creo que es una buena solución y definitivamente es fácil de seguir, depurar, ya que en realidad describe la ejecución del programa.
Por cierto: hay una segunda alternativa, pero requiere cambiar el código que estamos probando. Podríamos envolver a los alborotadores y trasladarlos a una clase separada:
podría envolverse como:
y eso es todo, pero como no quería crear otra clase para él, prefiero la primera.
fuente