Como é que eu posso testar uma classe Singleton com o DUnit?
Ou seria melhor eu utilizar outro padrão de projeto?
Daniel Grillo
Curtidas 0
Respostas
Anderson Farias
27/10/2009
Em q sentido exatamente? Testar um singleton não é diferente de testar uma classe qualquer. Alguma preocupação específica?
T+
T+
GOSTEI 0
Daniel Grillo
27/10/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.
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.
GOSTEI 0
Anderson Farias
27/10/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+
|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+
GOSTEI 0