I started writing some unit tests for my current project. I don't really have experience with it though. I first want to completely "get it", so I am currently using neither my IoC framework nor a mocking library.
I was wondering if there is anything wrong with providing null arguments to objects' constructors in unit tests. Let me provide some example code:
public class CarRadio
{...}
public class Motor
{
public void SetSpeed(float speed){...}
}
public class Car
{
public Car(CarRadio carRadio, Motor motor){...}
}
public class SpeedLimit
{
public bool IsViolatedBy(Car car){...}
}
Yet Another Car Code Example(TM), reduced to only the parts important to the question. I now wrote a test something like this:
public class SpeedLimitTest
{
public void TestSpeedLimit()
{
Motor motor = new Motor();
motor.SetSpeed(10f);
Car car = new Car(null, motor);
SpeedLimit speedLimit = new SpeedLimit();
Assert.IsTrue(speedLimit.IsViolatedBy(car));
}
}
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.
I am wondering if an object providing correct functionality without being fully constructed is a violation of SRP or a code smell. I have this nagging feeling that it does, but speedLimit.IsViolatedBy(motor)
doesn't feel right either - a speed limit is violated by a car, not a motor. Maybe I just need a different perspective for unit tests vs. working code, because the whole intention is to test only a part of the whole.
Is constructing objects with null in unit tests a code smell?
Motor
probably shouldn't have aspeed
at all. It should have athrottle
and compute atorque
based on the currentrpm
andthrottle
. It's the car's job to use aTransmission
to integrate that into a current speed, and to turn that into anrpm
to signal back to theMotor
... But I guess, you weren't in it for the realism anyway, were you?null
radio, the speed limit is correctly computed. Now you may want to create a test to validate the speed limit with a radio; just in case the behavior differs...