Is constructing objects with null in unit tests a code smell?
Sim. Observe a definição C2 de cheiro de código : "um CodeSmell é uma pista de que algo pode estar errado, não uma certeza."
The test runs fine. SpeedLimit needs a Car with a Motor in order to do its thing. It is not interested in a CarRadio at all, so I provided null for that.
Se você estiver tentando demonstrar que speedLimit.IsViolatedBy(car)
não depende do argumento CarRadio
passado para o construtor, provavelmente seria mais claro para o futuro mantenedor tornar essa restrição explícita introduzindo um teste duplo que falha no teste se for invocado.
Se, como é mais provável, você está tentando salvar o trabalho de criar um CarRadio
que você sabe que não é usado nesse caso, observe que
- isso é uma violação do encapsulamento (você está deixando que o fato de
CarRadio
não ser usado vaze para o teste)
- você descobriu pelo menos um caso em que deseja criar um
Car
sem especificar um CarRadio
Suspeito strongmente que o código está tentando dizer que você deseja um construtor que pareça
public Car(IMotor motor) {...}
e, em seguida, esse construtor pode decidir o que fazer com o fato de não haver CarRadio
public Car(IMotor motor) {
this(null, motor);
}
ou
public Car(IMotor motor) {
this( new ICarRadio() {...} , motor);
}
ou
public Car(IMotor motor) {
this( new DefaultRadio(), motor);
}
etc.
Its about if passing null to something else while testing SpeedLimit. You can see that the test is called "SpeedLimitTest" and the only Assert is checking a method of SpeedLimit.
Esse é um segundo cheiro interessante - para testar o SpeedLimit, você precisa construir um carro inteiro em torno de um rádio, mesmo que a única coisa com que o SpeedLimit provavelmente se preocupe seja a velocidade .
Isso pode ser uma indicação de que SpeedLimit.isViolatedBy
deveria aceitar uma interface de função que o carro implementa
interface IHaveSpeed {
float speed();
}
class Car implements IHaveSpeed {...}
IHaveSpeed
é um nome muito ruim; espero que a sua linguagem de domínio tenha uma melhoria.
Com essa interface, seu teste para SpeedLimit
pode ser muito mais simples
public void TestSpeedLimit()
{
IHaveSpeed somethingTravelingQuickly = new IHaveSpeed {
float speed() { return 10f; }
}
SpeedLimit speedLimit = new SpeedLimit();
Assert.IsTrue(speedLimit.IsViolatedBy(somethingTravelingQuickly));
}