2 votes

Comment implémenter le Builder Pattern en java @Test ?

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 ?

3voto

Mureinik Points 61228

Théoriquement, vous pourriez l'importer :

import com.example.Car.CarFactory;

Cependant, vous avez indiqué que vous ne pouvez pas modifier le code de test, vraisemblablement pas même pour ajouter des importations. Si c'est effectivement le cas, cela signifie que Carfactory doit être sa propre classe de premier niveau, et non une classe intérieure à l'intérieur de la classe Car .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X