Je dois écrire une implémentation pour un test unitaire donné, qui ne peut pas être modifié.
/**
* This is the car factory test. For all the tests to succeed, the implementations and the classes you
* think might be required, would have to be written.
*
* Existing tests cannot be modified unless you notice an error.
* You are free to create new tests in order to increase the coverage.
*
* The purpose of this exercise is to see the quality of the code written, how it is structured.
*
* A car factory build several car models using parts: engine, tires and chassis.
* All car parts have a quality level between 1 and 5 (inclusive). 1 being the lowest, 5 the highest.
*
* Cars have 4 external characteristics: top speed, acceleration, manoeuvrability and braking.
* Top speed is an integer expressed in kilometers per hour
* Acceleration is a string representation of a java.time.Duration: this is the time it takes for the vehicle to reach 100 km/h
* Manoeuvrability is an integer representing the maximum number of degrees the vehicle can turn at 50 km/h without drifting
* Braking is an integer that represents the number of meters it takes to stop the vehicle when going at 50 km/h
*
* Each level of "engine":
* - adds 30 km/h in top speed
* - removes 2s to the acceleration
* Each level of "tires":
* - removes 10% to the acceleration
* - adds 10 degrees to the manoeuvrability
* - removes 10% to the braking distance
* Each level of "chassis":
* - adds 5% to the top speed
* - adds 0.25s to the acceleration
* - adds 5 degrees to the manoeuvrability
* - adds 5 meters to the braking distance.
*
* Warning: all fixed-number impacts (like for top speed and braking) are applied before any percentage modifications granted by other parts.
*/
public class AppTest {
@Test(expected = IllegalArgumentException.class)
public void testFactoryCannotBuildIncompleteCars() {
CarFactory carFactory = new CarFactory();
carFactory.withEngine(1);
carFactory.build();
}
@Test
public void testModel1Creation() {
CarFactory carFactory = new CarFactory()
.withEngine(1)
.withTires(1)
.withChassis(1);
Car model1 = carFactory.build();
assertNotNull(model1);
}
/**
* This test also gives the base characteristics of cars
*/
@Test
public void testModel1Characteristics() {
CarFactory carFactory = new CarFactory()
.withEngine(1)
.withTires(1)
.withChassis(1);
Car model1 = carFactory.build();
assertEquals(100, model1.topSpeed());
assertEquals("PT15S", model1.acceleration());
assertEquals(20, model1.manoeuvrability());
assertEquals(50, model1.braking());
}
@Test
public void testModel2Characteristics() {
CarFactory carFactory = new CarFactory()
.withEngine(2)
.withTires(1)
.withChassis(1);
Car model1 = carFactory.build();
assertEquals(130, model1.topSpeed());
assertEquals("PT12S", model1.acceleration());
assertEquals(20, model1.manoeuvrability());
assertEquals(50, model1.braking());
}
@Test
public void testModel3Characteristics() {
CarFactory carFactory = new CarFactory()
.withEngine(5)
.withTires(5)
.withChassis(5);
Car model1 = carFactory.build();
assertEquals(264, model1.topSpeed());
assertEquals("PT4.2S", model1.acceleration());
assertEquals(80, model1.manoeuvrability());
assertEquals(42, model1.braking());
}
}
J'ai créé le modèle Builder pour satisfaire cette exigence. Mais vous ne pouvez pas créer la classe interne Builder sans instiller d'abord la classe externe.
package com.example;
import java.time.Duration;
public class Car {
private Integer topSpeed;
private Duration acceleration;
private Integer manoeuvrability;
private Integer braking;
public Car(CarFactory carFactory) {
}
public static class CarFactory {
private Integer topSpeed;
private Duration acceleration;
private Integer manoeuvrability;
private Integer braking;
public CarFactory(Integer topSpeed, Duration acceleration, Integer manoeuvrability, Integer braking) {
this.topSpeed = topSpeed;
this.acceleration = acceleration;
this.manoeuvrability = manoeuvrability;
this.braking = braking;
}
public CarFactory withEngine(Integer levels) {
for (int index = 0; index < levels; index++) {
this.acceleration = this.acceleration.minusSeconds(2);
this.acceleration = this.acceleration.minusSeconds(2);
}
return this;
}
public CarFactory withTires(Integer levels) {
for (int index = 0; index < levels; index++) {
this.manoeuvrability = this.manoeuvrability + 10;
this.acceleration = this.acceleration.minusSeconds(2);
this.braking = this.braking + 5;
}
return this;
}
public CarFactory withChassis(Integer levels) {
for (int index = 0; index < levels; index++) {
this.topSpeed = (int) (this.topSpeed + (topSpeed * 0.05));
this.acceleration = this.acceleration.plusMillis(25);
this.manoeuvrability = this.manoeuvrability + 5;
this.braking = this.braking + 5;
}
return this;
}
public Car build() {
return new Car(this);
}
}
}
car le modèle Builder doit utiliser une classe interne statique Builder. Ma question est la suivante : comment puis-je instancier le Builder sans faire référence à la classe externe comme l'exige le test unitaire ?