Java / Elon's Toy Car / Task 3 & 5

Hello,

I’m stuck with passing the tasks 3 and 5 from the ‘Elon’s Toy Car’ exercise.
Test 4 from Task 3 - failed:
Code Run:

@Test
@Tag(“task:3”)
@DisplayName(“The batteryDisplay method shows full battery message on a new car”)
public void new_car_battery_display() {
ElonsToyCar car = new ElonsToyCar();
assertThat(car.batteryDisplay()).isEqualTo(“Battery at 100%”);
}
Test Failure:
Message:
expected: “Battery at 100%”
but was: “Battery at 83%”
Exception: org.opentest4j.AssertionFailedError:
expected: “Battery at 100%”
but was: “Battery at 83%”
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at ElonsToyCarTest.new_car_battery_display(ElonsToyCarTest.java:38)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

I don’t understand why Elon's Toy Car in Java on Exercism returns “Battery at 83%” instead of “Battery at 100%” whereas my IntelliJ IDEA Community Edition displays “Battery at 100%”, what is expected.

@mdel2021 To answer, why your code does what you have shown, we need to see your code, too. Please post your code here as well, all of the file with the solution. Please use a code block (Preformatted text, Ctrl+e), not a quote as you did for the failure message.

Hello,
please find the code:

public class ElonsToyCar {
    private static int distance;
    private static int battery;

    public ElonsToyCar() {
    }

    public static ElonsToyCar buy() {
        ElonsToyCar.distance = 0;
        ElonsToyCar.battery = 100;
        System.out.println(batteryDisplay());
        System.out.println(distanceDisplay());
        return new ElonsToyCar();
    }

    public static String distanceDisplay() {
        return "Driven " + distance + " meters";
    }

    public static String batteryDisplay() {
        return "Battery at " + battery + "%";
    }

    public void drive() {
        if (battery >= 1) {
            distance += 20;
            battery--;
            System.out.println(batteryDisplay());
            System.out.println(distanceDisplay());
        } else {
            System.out.println("Battery empty");
        }
    }
}

As I written previously, tasks 1,2,4,6 are passed.
The following tests to tasks 3 and 5 are failing:

Task 3 - test 4:

@Test
@Tag("**task:3**")
@DisplayName("**The batteryDisplay method shows full battery message on a new car**")
public void new_car_battery_display() {
    ElonsToyCar car = new ElonsToyCar();
    assertThat(car.batteryDisplay()).isEqualTo("Battery at 100%");
}
Message: 
expected: "Battery at 100%"
 but was: "Battery at 83%"
Exception: org.opentest4j.AssertionFailedError: 
expected: "Battery at 100%"
 but was: "Battery at 83%"
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
	at ElonsToyCarTest.new_car_battery_display(ElonsToyCarTest.java:38)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

Task 5 - test 7:

@Test
@Tag("**task:5**")
@DisplayName("**The batteryDisplay method shows the correct message after driving once**")
public void battery_display_after_driving_once() {
    ElonsToyCar car = new ElonsToyCar();
    car.drive();
    assertThat(car.batteryDisplay()).isEqualTo("Battery at 99%");
}
Message: 
expected: "Battery at 99%"
 but was: "Battery at 98%"
Exception: org.opentest4j.AssertionFailedError: 
expected: "Battery at 99%"
 but was: "Battery at 98%"
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
	at ElonsToyCarTest.battery_display_after_driving_once(ElonsToyCarTest.java:70)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

Task 5 - test 8:

@Test
@Tag("**task:5**")
@DisplayName("**The batteryDisplay method shows the correct battery percentage after driving multiple times**")
public void battery_display_after_driving_multiple_times() {
    ElonsToyCar car = new ElonsToyCar();
    for (int i = 0; i < 23; i++) {
        car.drive();
    }
    assertThat(car.batteryDisplay()).isEqualTo("Battery at 77%");
}
Message: 
expected: "Battery at 77%"
 but was: "Battery at 0%"
Exception: org.opentest4j.AssertionFailedError: 
expected: "Battery at 77%"
 but was: "Battery at 0%"
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
	at ElonsToyCarTest.battery_display_after_driving_multiple_times(ElonsToyCarTest.java:83)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

Task 5 - test 9:

@Test
@Tag("**task:5**")
@DisplayName("**The batteryDisplay method shows battery empty after draining all battery**")
public void battery_display_when_battery_empty() {
    ElonsToyCar car = new ElonsToyCar();
    // Drain the battery
    for (int i = 0; i < 100; i++) {
        car.drive();
    }
    // Attempt to drive one more time (should not work)
    car.drive();
    assertThat(car.batteryDisplay()).isEqualTo("Battery empty");
}
Message: 
expected: "Battery empty"
 but was: "Battery at 0%"
Exception: org.opentest4j.AssertionFailedError: 
expected: "Battery empty"
 but was: "Battery at 0%"
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
	at ElonsToyCarTest.battery_display_when_battery_empty(ElonsToyCarTest.java:100)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

This test is the one that shows, what is wrong. The test says: when creating a new instance, the battery needs to be full. As far as I can tell this is not done in your code. You declare instance variables and use them, but you do not initialise them.

Is that clear enough to help?

Hello, thanks for the answer. I am not sure I understood correctly where instance variables are not initialized, especially in online runner because my IDEA does not return any issues to the following code:

public class ElonsToyCar {
    public int distance;
    public int battery;

    public ElonsToyCar(int battery, int distance) {
        this.battery = battery;
        this.distance = distance;
    }

    public int getBattery() {
        return battery;
    }

    public void setBattery(int battery) {
        this.battery = battery;
    }

    public int getDistance() {
        return distance;
    }

    public void setDistance(int distance) {
        this.distance = distance;
    }

   public static ElonsToyCar buy() {
        return new ElonsToyCar(100, 0);
    }

    public String distanceDisplay() {
        return "Driven " + getDistance()+ " meters";
    }

    public String batteryDisplay() {
        return "Battery at " + getBattery() + "%";
    }

    public void drive() {
        if (getBattery() >= 1) {
            setDistance(getDistance()+20);
            setBattery(getBattery()-1);
            System.out.println(batteryDisplay());
            System.out.println(distanceDisplay());
        } else {
            System.out.println("Battery empty");
        }
    }
}

Online Exercism runner

We received the following error when we ran your code:
./src/test/java/ElonsToyCarTest.java:29: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length./src/test/java/ElonsToyCarTest.java:37: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length./src/test/java/ElonsToyCarTest.java:45: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length./src/test/java/ElonsToyCarTest.java:54: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length./src/test/java/ElonsToyCarTest.java:67: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length./src/test/java/ElonsToyCarTest.java:77: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length./src/test/java/ElonsToyCarTest.java:90: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length./src/test/java/ElonsToyCarTest.java:107: error: constructor ElonsToyCar in class ElonsToyCar cannot be applied to given types;
        ElonsToyCar car = new ElonsToyCar();
                          ^
  required: int,int
  found:    no arguments
  reason: actual and formal argument lists differ in length

local IDE:

Battery at 100%
Driven 0 meters
Battery at 99%
Driven 20 meters
Battery at 98%
Driven 40 meters
Battery at 97%
Driven 60 meters
Battery at 96%
Driven 80 meters

The exercise expects you to write a constructor that takes zero arguments. The unit tests create a car using zero arguments. You wrote code which isn’t consider with the unit tests. You’re not running the unit tests locally.

1 Like

Okey. So, after returning to using a zero-parameters constructor, all unit tests to the task 3 and 5 are still failed with the same test results as in the Java / Elon's Toy Car / Task 3 & 5 - #3 by mdel2021.

public class ElonsToyCar {
    public static int distance;
    public static int battery;

    public ElonsToyCar() {
    }

    public static int getBattery() {
        return battery;
    }

    public void setBattery(int battery) {
        ElonsToyCar.battery = battery;
    }

    public static int getDistance() {
        return distance;
    }

    public void setDistance(int distance) {
        ElonsToyCar.distance = distance;
    }

   public static ElonsToyCar buy() {
        ElonsToyCar car = new ElonsToyCar();
        car.setDistance(0);
        car.setBattery(100);
        System.out.println(distanceDisplay());
        System.out.println(batteryDisplay());
        return car;
    }

    public static String distanceDisplay() {
        return "Driven " + getDistance()+ " meters";
    }

    public static String batteryDisplay() {
        return "Battery at " + getBattery() + "%";
    }

    public void drive() {
        if (getBattery() >= 1) {
            setDistance(getDistance()+20);
            setBattery(getBattery()-1);
            System.out.println(distanceDisplay());
            System.out.println(batteryDisplay());
        } else {
            System.out.println("Battery empty");
        }
    }
}

​​1. Do you understand what this test is doing?
2. Do you understand what this test is expecting and why?
3. Do you understand what your code returns and how it differs?
4. Do you understand why your code is returning what it returns?

@mdel2021 The difference between your local IDEA and Exercism online environment seems to be: IDEA does not run all the tests. Or it does not run the Exercism tests at all. But your problem has to do with making multiple instances of ElonsToyCar.

When I compare the two versions of your code, I see more than one change. The constructor is required to remain without arguments, but still you need to assign values to instance variables in it. And you should read again about static on variables and what happens when multiple instances are created.

I hope that helped to understand what your code does and where it differs from what the tests are expecting.