1

I have the following class

data class CarDefects(
    private val _carModel: CarModel,
    private val _affectedYearsOfIssue: List<Year>,
    private val _defectCode: String
) {

    init {
        validateDefectCode(_defectCode)

    }
}

Validating function

fun validateDefectCode(defectCode: String) {
    val pattern = Pattern.compile("^[a-zA-Z0-9-]*\$")
    val m = pattern.matcher(defectCode)
    if (defectCode.length !in 4..4) {
        throw InvalidDefectCodeException(defectCode, "Defect code must be 4 characters long")
    }
    if (!m.matches()) {
        throw InvalidDefectCodeException(defectCode, "Defect code can only contain alphanumeric characters")
    }
}

And the exception class:

class InvalidDefectCodeException(_defectCode:String, message:String):
    IllegalArgumentException("Invalid defect code $_defectCode. $message") {
}

I'm trying to test the validating function with JUnit

import car.exceptions.InvalidDefectCodeException
import car.validators.carDefectsValidators.validateDefectCode
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import java.time.Year
import kotlin.test.assertFailsWith

internal class CarDefectsTest {

    val carModel = CarModel(Brand.BMW, "X5", 199219)
    val carModel2 = CarModel(Brand.AUDI, "X434", 199219)


    val defect = CarDefects(carModel, listOf(Year.of(2020), Year.of(2021)), "SE2@")
    val defect2 = CarDefects(carModel2, listOf(Year.of(2020), Year.of(2021)), "122F4")

    @Test
    fun testDefectCodeExceptions() {

        val exception = Assertions.assertThrows(InvalidDefectCodeException::class.java) {
            validateDefectCode(defect.getDefectCode())
        }
    }

    @Test
    fun testDefectCodeExceptions2() {

        assertFailsWith<InvalidDefectCodeException> {
            validateDefectCode(defect2.getDefectCode())
        }
    }
}

Both tests fail, however expected exceptions are still thrown, from what i understand shouldn't both tests pass?

I've already seen the following post: Test expected exceptions in Kotlin

indee423
  • 121
  • 1
  • 11

1 Answers1

0

Inside class CarDefects, you're having this init block:

init {
    validateDefectCode(_defectCode)
}

Hence, the exception will be thrown during construction.

Let's test the constructor instead with a stripped down CarDefects class. The following tests are passing on my computer.

import car.exceptions.InvalidDefectCodeException
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import kotlin.test.assertFailsWith

data class CarDefects(
    private val defectCode: String
) {
    init {
        validateDefectCode(defectCode)
    }
}

internal class CarDefectsTest {

    @Test
    fun testDefectCodeExceptions() {
        Assertions.assertThrows(InvalidDefectCodeException::class.java) {
            CarDefects(defectCode = "SE2@")
        }
    }


    @Test
    fun testDefectCodeExceptions2() {
        assertFailsWith<InvalidDefectCodeException> {
            CarDefects(defectCode = "122F4")
        }
    }
}
Roar S.
  • 8,103
  • 1
  • 15
  • 37