Desafortunadamente está usando getResultState()
para crear el objeto ResultState
, que es realmente su bloqueador.Consideremos refactorización al siguiente interfaz:
protected ResultState initResultState ()
{
this.resultState = new ResultState();
// Initialization Logic...
return this.resultState;
} // END initResultState
public ResultState getResultState ()
{
if (this.resultState === null)
{
return this.initResultState();
}
return this.resultState;
} // END getResultState()
Desde esta posición, es más fácil poner a prueba su método de obtención. Definir una clase descendiente que devuelve un conocido ResultState
del trozo de initResultState()
que puede ser interrogado, es decir:
/**
* The test fixutre's initResultState() method merely returns a simple Stub of
* the ResultState object, which can be more easily interrogated.
*/
public ResultState initResultState ()
{
return new Stub_ResultState();
} // END initResultState
Eso todavía le deja con la initResultState()
protegido, por supuesto. Considere el siguiente refactorización:
protected ResultState initResultState (ResultState newResultState)
{
this.resultState = newResultState;
// Initialization Logic...
return this.resultState;
} // END initResultState
public ResultState getResultState ()
{
if (this.resultState === null)
{
return this.initResultState(new ResultState());
}
return this.resultState;
} // END getResultState
Esto le permite reemplazar el método getResultState()
en una clase descendiente de tal manera que se puede pasar otro objeto ResultState
del trozo a ser manipulado e interrogado después, por ejemplo:
/**
* The test fixture's getResultState() method always acts as a passthrough for
* initResultState(), which is protected, so that the output of the protected
* method can be interrogated.
*/
public ResultState getResultState ()
{
return this.initResultState(new Stub_ResultState());
} // END getResultState
Desde esta posición, necesita dos dispositivos de prueba: uno que anula el comportamiento de initResultState()
para probar la funcionalidad de los captadores; otro que anula el comportamiento de getResultState()
para probar el comportamiento de initResultState()
. Ambos usan una instancia de la clase Stub_ResultState
, que es necesariamente un descendiente de la clase ResultState
, pero proporciona acceso público a los valores internos de su objeto principal para la interrogación en pruebas unitarias.
Espero que tenga sentido, pero no dude en pedir aclaraciones.
+1 - casi palabra por palabra lo que iba a decir –
Jon, buena pregunta - lo que es importante sobre el resultado. Después de pensar en esto, lo más importante sobre el resultado es que debe ser un objeto esperado por los métodos que lo usarán.Y esto se logra en la sección // LOGIC // del código, donde LOGIC manipula los campos de "esto" Así que hice los siguientes escenarios de prueba: 1. Configuré setters y getters para estos campos 2. set ellos con + ve (valores buenos) y -ve (valores incorrectos) 3. y compilarlo sin excepciones ... esto son pruebas triviales pero un buen comienzo-- gracias –