tutorial objetos metodos introduccion herencia ejemplos clases scala testing scalatest

objetos - ¿Cómo se puede probar un método de clase privado en Scala?



scala ejemplos (8)

Tengo un objeto complementario con un método privado, así:

package com.example.people class Person(val age: Int) object Person { private def transform(p: Person): Person = new Person(p.age + 1) }

Me gustaría probar este método, con algo como:

class PersonSpec extends FlatSpec { "A Person" should "transform correctly" in { val p1 = new Person(1) val p2 = Person.transform(p1) // doesn''t compile, because transform is private! assert( p2 === new Person(2) ) } }

¿Alguna ayuda para tener acceso a código de prueba en métodos privados?

En realidad, tal como está escrito, podría crear una subclase de Person , pero ¿qué Person si la Person es declarada final o sealed ?

¡Gracias!


En términos generales: si quiere probar efectivamente su código, primero debe escribirlo para poder probarlo.

Scala implementa el paradigma funcional y usa objetos inmutables por diseño, las "clases de casos" son ejemplos (mi opinión es que la clase Persona debe ser una clase de caso).

La implementación de los métodos privados tiene sentido si los objetos tienen un estado mutable, en este caso es posible que desee proteger el estado de los objetos. Pero si los objetos son inmutables, ¿por qué implementar métodos como privados? En su ejemplo, el método produce una copia de Person, ¿por qué motivo desea hacerlo privado? No veo ninguna razón.

Te sugiero que pienses sobre esto. Nuevamente, si quiere probar efectivamente su código, debe escribirlo para poder probarlo.


Estoy en el medio cuando se trata de probar todo. Normalmente no pruebo todo, pero a veces es realmente útil poder probar una función privada sin tener que modificar mi código para hacerlo posible. Si está usando ScalaTest, puede usar PrivateMethodTester para hacerlo.

import org.scalatest.{ FlatSpec, PrivateMethodTester } class PersonSpec extends FlatSpec with PrivateMethodTester { "A Person" should "transform correctly" in { val p1 = new Person(1) val transform = PrivateMethod[Person](''transform) assert(p2 === invokePrivate transform(p1)) } }

Puede que eso no sea exactamente lo que quieres hacer, pero entiendes la idea.


La necesidad de probar los métodos privados es un olor de diseño.

O los prueba a través de su API pública, que está bien si son pequeños y solo son métodos auxiliares, o, lo que es más probable, contiene una lógica / responsabilidad diferente y se debe mover a otra clase que se utilice por delegación en la Persona. Entonces probarías primero la API pública de esa clase.

Vea una respuesta relacionada para más detalles.

Es probable que pueda acceder utilizando la reflexión de Java / Scala, pero es solo una solución para el problema de diseño. Aún así, si es necesario, consulte una respuesta de Java relacionada sobre cómo hacerlo .


La respuesta de @ jlegler aquí me ayudó, pero aún me quedaba algo de depuración antes de que las cosas funcionaran, así que pensé en escribir exactamente lo que se necesita para esto aquí.

Probar:

class A object A { private def foo(c: C): B = {...} }

utilizar:

val theFuncion = PrivateMethod[B](''foo) val result = A invokePrivate theFunction(c)

Tenga en cuenta las ubicaciones de A, B


No creo que las pruebas unitarias tengan que ver con la prueba del contrato de la clase; se trata de probar la funcionalidad simple (unidad).

Además, no creo que sea una buena idea hacer públicos algunos métodos solo para que sean fácilmente comprobables. Creo que mantener la API lo más estrecha posible es una buena manera de ayudar a otros desarrolladores a usar su código (IDE no sugerirá métodos privados) y entender el contrato.

Además, no deberíamos poner todo en un solo método. Entonces, a veces podemos poner un poco de lógica en un método privado ... y por supuesto queremos probarlo también. Probarlo a través de la API pública aumentará la complejidad de su prueba. (Otra opción es mover la lógica del método privado a otra clase auxiliar y probarla allí ... esta clase no será utilizada directamente por los desarrolladores y no saturará la API)

Los chicos de scalatest, creo, añadieron PrivateMethodTester para un propósito.


Personalmente, digo que hagamos que todo sea público y simplemente antepongamos con _ o __ para indicar que otros desarrolladores no deberían usarlo.

Me doy cuenta de que esto es Scala y no Python, pero a pesar de todo, "todos consentimos adultos aquí".

Los métodos "privados" en realidad no son privados ( por ejemplo ) y ciertamente no son seguros, entonces ¿por qué hacer la vida más difícil para lo que es esencialmente un contrato social? Prepáralo y listo: si otro desarrollador quiere hurgar en lugares oscuros, o tienen una buena razón o se merecen lo que obtienen.


Puede declarar que su método es un paquete privado:

private[people] def transform(p: Person): Person = new Person(p.age + 1)

Si coloca PersonSpec en el mismo paquete, podrá acceder a él.

Te dejo a ti decidir si es realmente prudente probar la unidad de un método privado :)


un posible trabajo sería probar indirectamente el método privado: probar un método público que llama al método privado