Array
(
)

Como é que eu posso testar uma classe Singleton com o DUnit?

Daniel Grillo
   - 27 out 2009

Ou seria melhor eu utilizar outro padrão de projeto?

Anderson Farias
   - 27 out 2009

Em q sentido exatamente? Testar um singleton não é diferente de testar uma classe qualquer. Alguma preocupação específica?

T+

Daniel Grillo
   - 27 out 2009

Não é bem assim Anderson.

Vamos supor que você criou uma classe singleton e criou um método lá dentro chamado AdicionaUm ao atributo Resultado, como abaixo:

procedure AdicionaUm;
begin
    Inc(Resultado);
end;

Dai você vai fazer os testes na seguinte ordem:

procedure TestResultadoDeveSerIgualAUm;
var
    CEx: TClasseEx;
begin
    CEx := TClasseEx.GetInstance;
    CEx.AdicionaUm;
    Check(Resultado = 1);
end;

procedure TestResultadoDeveSerIgualAZero;
var
    CEx: TClasseEx;
begin
    CEx := TClasseEx.GetInstance;
    Check(Resultado = 0);
end;

Então o segundo teste não irá passar pq o resultado será igual a um.

Essa é a minha preocupação.

Anderson Farias
   - 27 out 2009

|Vamos supor que você criou uma classe singleton e criou um método lá dentro chamado
|AdicionaUm ao atributo Resultado, como abaixo:
|...
|Então o segundo teste não irá passar pq o resultado será igual a um.
|Essa é a minha preocupação.

Perfeito. Bom, como acontece com qualquer classe é importante compreender seu comportamento para testá-la. No exemplo que vc passou existem formas diferentes de ver:

Testando 'TestResultadoDeveSerIgualAZero' sempre antes de 'TestResultadoDeveSerIgualAUm' testa q a classe está sendo iniciada corretamente em zero (admitindo isto).

Testando 'TestResultadoDeveSerIgualAUm' sempre antes de 'TestResultadoDeveSerIgualAZero' testa q a classe o singleton está funcionando corretamente pois a instância na segunda chamada é a mesma da anterior.

É verdade q em testes unitários é uma boa prática q os testes sejam independentes uns dos outros e da ordem q são executados, mas isto não é 100% válido, é apenas uma meta geral.

Sendo um singleton eu tenho q ter em mente q a 'vida' do objeto deve durar (normalmente) durante todo o teste e isto é na verdade o q desejamos.

Existe ainda outra forma de abordar o caso. Se a classe precisa no intervalo de ações ser 'reinicializada' então o singleton deve prover tal meio, como um método Reset por exemplo que seria responsável por deixar a classe em seu estado inicial. Ou ainda, permitindo q o singleton seja destruído para construir uma nova instância na próxima chamada (inclusive muitas implementações de singleton permitem isso -- nada q seja utilizado em aplicações reais mas quem sabe útil para seu caso)

T+