直積集合を作るライブラリを作りました。
GitHub - doilux/cartesian-product
これを使ってテストコードを書いてみます。 (注意:上記のライブラリのIFを変えたので、下記コードは参考です)
プロダクトコードはこんな感じ
public class DrivingResolver {
public static boolean canDrive(Driver driver, Vehicle vehicle) {
return (driver.equals(Driver.TAKA) && vehicle.equals(Vehicle.MOTOR_CYCLE))
|| (driver.equals(Driver.JURI) && vehicle.equals(Vehicle.CAR));
}
}
public enum Driver {
TAKA, HAJIME, JURI;
}
public enum Vehicle {
MOTOR_CYCLE, CAR;
}
↓のようなテストは書きたくないorz なぜなら、Enumの値が増えるたびにwhereブロックのパターンが増えるため。 スケールしないコードと言えます。
def "CanDrive"() {
expect:
DrivingResolver.canDrive(driver, vehicle) == result
where:
driver | vehicle || result
Driver.TAKA | Vehicle.MOTOR_CYCLE || true
Driver.TAKA | Vehicle.CAR || false
Driver.HAJIME | Vehicle.MOTOR_CYCLE || false
Driver.HAJIME | Vehicle.CAR || false
Driver.JURI | Vehicle.MOTOR_CYCLE || false
Driver.JURI | Vehicle.CAR || true
}
で、こうしてみます。
def "CanDrive"() {
setup:
def allPattern = CartesianProductResolver.resolve(
new HashSet<Object>() {{addAll(Driver.values())}},
new HashSet<Object>() {{addAll(Vehicle.values())}}
)
def driverblePattern = [[Driver.TAKA, Vehicle.MOTOR_CYCLE], [Driver.JURI, Vehicle.CAR]]
def notDriverblePattern = allPattern.stream().filter {
!driverblePattern.contains(it)
}.collect(Collectors.toList())
expect:
driverblePattern.stream().filter {
!DrivingResolver.canDrive(it.get(0), it.get(1))
}.collect(Collectors.toList()).size() == 0
notDriverblePattern.stream().filter {
DrivingResolver.canDrive(it.get(0), it.get(1))
}.collect(Collectors.toList()).size() == 0
}
こうすれば、Enum増えてもテストコード量はそんなに増えないです。