Need for Speed: Task 3 - "Drive the Car" description and test are different

I’m trying to get a deeper understanding of Go by implementing tests locally, and I’m having difficulty understanding task 3 - Drive the car, of the Need For Speed exercise.

The specification and example for this task are:

Implement the Drive function that updates the number of meters driven based on the car’s speed, and reduces the battery according to the battery drainage. If there is not enough battery to drive one more time the car will not move:

speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car = Drive(car)
// => Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}

When a new car is created (by calling NewCar method), the default battery is always 100 and the default distance is always 0.

The test function for this task calls Drive directly without calling NewCar. In doing so, a custom Car object with non-default values for battery and distance are passed to the Drive function.

So my question is:

  • Is car := NewCar(speed, batteryDrain) incorrect and should not be a part of the example ?

  • Or is the test incorrect because it calls Drive directly without calling NewCar() ?

In my opinion it’s a neither nor.

The test is for testing Drive without additional dependencies and with pre-defined situations of a Car. Is not necessarily a new car. It want to test how Drive will behave for certain Cars.

On the other hand, when using in your code you would start with a New... function for initialization.

The test is for testing Drive without additional dependencies and with pre-defined situations of a Car. Is not necessarily a new car. It want to test how Drive will behave for certain Cars.

If this is the case, why is the task description:

speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}

instead of:

speed := 5
batteryDrain := 2
car := Car{speed: 5, batterDrain: 2}
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}

?

As I said: You usually offer Initializers or constructors for your types, so they are used correctly. It’s still only a convention, unless your internals aren’t exported.

But tests go often deeper into your structure and define the states raw and directly, to simulate preconditions. The NewCar itself is tested, too.

The test is not a blueprint for how to use your type.

I understand initializers, constructors, and convention. What you’re saying is contradictory to the task specification:

The test is for testing Drive without additional dependencies and with pre-defined situations of a Car.

Why not remove car := NewCar(speed, batteryDrain) from the task’s code block and create a custom car object with example values for speed, distance, battery, and battery drain?

Is not necessarily a new car. It want to test how Drive will behave for certain Cars.

Again, why is this stated in the task description is the form of car := NewCar(speed, batteryDrain) ?