Estoy probando suerte con Mockito para escribir pruebas unitarias. Tengo una clase que necesita ser probada como a continuación-
open class Employee { fun setDetails(name: String, age: Int) { setName(name) setAge(age) } fun setName(name: String) { } fun setAge(age: Int) { } }A continuación se muestra mi clase de prueba
class EmployeeTest { @Mock lateinit var emp: Employee @Before fun setup() { MockitoAnnotations.initMocks(this) } @Test fun testDetail() { emp.setDetails("Henry", 23) verify(emp, times(1)).setAge(23) } }Aquí está mi problema
Cuando lo hago -
verify(emp, times(1)).setAge(23)Esto me da un éxito, porque setAge se llama una vez en setDetails() de Employee.kt. Entonces eso funciona bien para mí
Pero cuando lo hago-
verify(emp, never()).setAge(23)Esto todavía me da éxito, aunque el método se llama en setDetails(). ¿No debería fallar este caso de prueba?
Por favor, ayúdame a entender esto. No he sido capaz de averiguar por qué sucede esto.
EDITAR Esto es lo que funcionó para mí. Usé un espía en lugar de un simulacro. Sin embargo, también tuve que declarar los métodos como abiertos en Kotlin.
Como mencionó @kcoppock, su pregunta incluye un uso indebido de un simulacro. Debería usar simulacros para eliminar las dependencias a fin de controlar su comportamiento.
En su caso, la unidad bajo prueba es la clase Employee y sus métodos asociados. En general, no desea simular la unidad bajo prueba porque quiere saber (a partir de la prueba de su unidad) si su clase se está comportando como debería. Para lograr eso, querrá usar una instancia real de un Employee , y no un simulacro.
Si insiste en usar verify en la instancia de Employee , puede crear un spy .
@Test fun setDetails_adjustsAge() { val employee = spy(Employee()) employee.setDetails("Henry", 23) assertEquals(23, employee.age) verify(emp, times(1)).setAge(23) }Aquí hay algunas referencias para leer más:
Documentación oficial de Mockito sobre espías: http://static.javadoc.io/org.mockito/mockito-core/2.24.0/org/mockito/Mockito.html#13
Tutorial sobre cómo usar Mockito.spy https://www.baeldung.com/mockito-spy
Diferencias entre simulacro y espía: https://www.toptal.com/java/a-guide-to-everyday-mockito
Entonces, su problema aquí es que en realidad no quiere usar un simulacro. Cuando usa un simulacro, debe definir el comportamiento de cualquier método que llame en esa instancia. Entonces, cuando llama a emp.setDetails("Henry", 23) , no hay implementación para ese método, por lo que no sucede nada. No se usará el comportamiento definido en la clase Employee , ya que emp es solo una instancia falsa de Employee que no ha definido ningún comportamiento.
Para su escenario de prueba, debería preferir usar una instancia real y validar el resultado final en lugar del comportamiento interno. Por ejemplo:
@Test fun setDetails_adjustsAge() { val employee = Employee() employee.setDetails("Henry", 23) assertEquals(23, employee.age) }