Pregunta

Tengo una clase en la que estoy haciendo pruebas de unidad con DUnit. Tiene una serie de métodos, algunos métodos públicos y métodos privados.

type
  TAuth = class(TDataModule)
  private
    procedure PrivateMethod;
  public
    procedure PublicMethod;
  end;

Para escribir una prueba de unidad para esta clase, tengo que hacer públicos todos los métodos.

¿Hay alguna forma diferente de declarar los métodos privados para que aún pueda probarlos pero no son públicos?

¿Fue útil?

Solución

No necesitas hacerlos públicos. Protegido hará. Luego, puede subtipo la clase para la prueba de unidad y resaltar los métodos protegidos. Ejemplo:

type
  TAuth = class(TDataModule)
  protected
    procedure MethodIWantToUnitTest;
  public
    procedure PublicMethod;
  end;

Ahora puedes subtitularlo para tu prueba de unidad:

interface

uses
  TestFramework, Classes, AuthDM;

type
  // Test methods for class TAuthDM
  TestAuthDM = class(TTestCase)
     // stuff
  end;

  TAuthDMTester = class(TAuthDM)
  public
    procedure MethodIWantToUnitTestMadePublic;
  end;

implementation

procedure TAuthDMTester.MethodIWantToUnitTestMadePublic;
begin
  MethodIWantToUnitTest;
end;

Sin embargo, si los métodos que desea realizar la prueba unitaria están haciendo las cosas tan íntimamente con el módulo de datos que no es seguro tenerlos a excepción de privados, entonces debería considerar refactorizar los métodos para separar el código que necesita. para ser probado en la unidad y el código que accede a las entrañas del módulo de datos.

Otros consejos

Es un poco intrincado, pero creo que este es el enfoque más simple y claro. Utilice esta directiva de compilación condicional:

  {$IfNDef TEST}
  private
  {$EndIf}

Su proyecto de prueba de unidad debe definir PRUEBA en proyecto ? conditional define . Sin una especificación de visibilidad, se publican.

Cuidado: si la visibilidad privada no es la primera en la declaración de clase, obtendrá la definición anterior. Una forma más segura, pero más detallada y menos clara, sería:

  private
  {$IfDef TEST}
  public
  {$EndIf}

Esto tiene muchas ventajas sobre la subclasificación u otros enfoques:

  • Sin complejidad adicional: no hay clases adicionales en su código.
  • Nadie puede "equivocadamente" Subclase y anule su clase: usted preserva su arquitectura.
  • Cuando dices que un método está protegido, de alguna manera esperas que se invalide. Usted está diciendo esto para quién está leyendo su código. Un método protegido que no debería ser anulado confundirá a sus lectores de código, rompiendo mi primer principio de programación: " el código debe estar escrito para que lo lean otros seres humanos. & Quot;
  • DUnit está en su propia unidad, no incluida en todas partes.
  • No tocas el RTTI desordenado.

Creo que es una solución más clara y mejor que la respuesta seleccionada.

Cuando uso esto, también configuro el proyecto de prueba para colocar los objetos de compilación en un directorio diferente del proyecto principal. Esto evita que los binarios con la directiva TEST se mezclen con el otro código.

Recomiendo el " XUnit Test Patterns " libro de Gerard Meszaros:

Subclase específica de la prueba

  

Pregunta : ¿Cómo podemos hacer código?   comprobable cuando necesitamos acceder   estado privado del SUT?

     

Respuesta : agrega métodos que exponen la   Estado o comportamiento requerido por la prueba.   a una subclase del SUT.

     

... Si el sistema bajo prueba (SUT) no estaba   Diseñado específicamente para ser comprobable,   podemos encontrar que la prueba no puede obtener   Acceso a estado que debe   Inicializar o verificar en algún momento en   la prueba.

El artículo también explica cuándo usarlo y qué riesgos conlleva.

Coloque el código DUnit dentro de su unidad. A continuación, puede acceder a cualquier cosa que desee.

En general, cuando estoy en esta situación, a menudo me doy cuenta de que estoy violando el principio de responsabilidad única. Por supuesto, no sé nada sobre su caso específico, pero PUEDE, que los métodos privados deberían estar en su propia clase. El TAuth tendría una referencia a esta nueva clase en su sección privada.

Con RTTI extendido (Delphi 2010 y más reciente), invocar métodos privados a través de RTTI es otra opción. Esta solución también es la respuesta mejor calificada en ¿Cómo pruebo una clase que tiene métodos privados, campos o clases internas?

{$IFNDEF UNITEST}
private
{$ENDIF}

Solución simple, que apenas es un hack. Con frecuencia necesito probar métodos privados y esta técnica agrega la menor complicación posible.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top