【问题标题】:How to test a function in Kotlin with Junit如何使用 Junit 在 Kotlin 中测试函数
【发布时间】:2025-11-27 18:35:01
【问题描述】:

我用 Kotlin 编写了一个程序。该程序运行良好,但我仅通过运行程序来测试该功能。我想我知道问题出在哪里,但我不知道如何修改测试。提前致谢!

class Dice {
var firstDice = 1
var secondDice = 1
var thirdDice = 3
var fourthDice = 2
var fifthDice = 2
val dices: MutableList<Int> = ArrayList()

fun throwDices() {
    firstDice = Random.nextInt(1,7)
    dices.add(firstDice)
    println("Eldobtad a kockákat, az első kocka értéke: $firstDice")
    secondDice = Random.nextInt(1,7)
    dices.add(secondDice)
    println("A második kocka értéke: $secondDice")
    thirdDice = Random.nextInt(1,7)
    dices.add(thirdDice)
    println("A harmadik kocka értéke: $thirdDice")
    fourthDice = Random.nextInt(1,7)
    dices.add(fourthDice)
    println("A negyedik kocka értéke: $fourthDice")
    fifthDice = Random.nextInt(1,7)
    dices.add(fifthDice)
    println("Az ötödik kocka értéke: $fifthDice")
    dices.sort()
    println(dices)
}

fun winningCheck() :Int {
    if(dices[0] == dices[1] && dices[0] == dices[2] && dices[0] == dices[3] && dices[0] == dices[4] ) {
        return 15
    }
    else if(dices[0] == dices[1] && dices[0] == dices[2] && dices[0] == dices[3]) {
        return  9
    }
    else if (dices[0] == dices[1] && dices[0] == dices[2] && dices[3] == dices[4]) {
        return 5
    }
    else if(dices[0] == dices[1] && dices[0] == dices[2] || dices[1] == dices[2] && dices[1] == dices[3] ||
            dices[2] == dices[3] && dices[2] == dices[4]) {
        return 3
    }
    else if(dices[0] == dices[1] && dices[2] == dices[3] ||
            dices[1] == dices[2] && dices[3] == dices[4] ||
            dices[0] == dices[1] && dices[3] == dices[4]) {
        return  2
    }else if (dices[0] == dices[1] || dices[1] == dices[2] || dices[2] == dices[3] || dices[3] == dices[4]) {
        return 1
    }
    else
        return 0
}

}

这是类,我要测试,这里是测试代码:

class DiceTest {

private val dice = Dice()
private val dices: MutableList<Int> = ArrayList()

@Before
fun init() {
    dice.firstDice = 1
    dice.secondDice = 1
    dice.thirdDice= 1
    dice.fourthDice = 1
    dice.fifthDice = 1

    dices.add(dice.firstDice)
    dices.add(dice.secondDice)
    dices.add(dice.thirdDice)
    dices.add(dice.fourthDice)
    dices.add(dice.fifthDice)
}

@Test
fun checkingFiveOfAKind () {
    assertEquals(15,dice.winningCheck())
}

这是错误代码:

【问题讨论】:

  • 与问题无关,但“骰子”不是英文单词——“骰子”已经是复数;单数是“死”。一个骰子,两个骰子。
  • 是的,我知道,就像老鼠一样。但是我的眼睛更容易使用骰子和骰子。
  • (如果是我,我想我会更喜欢“死”和“死”!  常规,更接近标准术语。)
  • 死亡和死亡提醒我有人死了。匈牙利语也有更多含义的词。如果我的英语不完美,请原谅。 ??????

标签: kotlin junit


【解决方案1】:

我认为您的示例可以简化为问,为什么这段代码不起作用:

@Test
fun checkingFiveOfAKind() {
    val dices: MutableList<Int> = ArrayList()
    dices.add(1)
    dices.add(1)
    dices.add(1)
    dices.add(1)
    dices.add(1)
    
    val anotherDices: MutableList<Int> = ArrayList()

    val result :Int
    if(anotherDices[0] == anotherDices[1] 
       && anotherDices[0] == anotherDices[2] 
       && anotherDices[0] == anotherDices[3] 
       && anotherDices[0] == anotherDices[4] ) {
       result = 15
    } else {
       result = 0
    }
 
    assertEquals(15, result)
}

但是这段代码确实有效:

@Test
fun checkingFiveOfAKind() {
    val dices: MutableList<Int> = ArrayList()
    dices.add(1)
    dices.add(1)
    dices.add(1)
    dices.add(1)
    dices.add(1)
    
    val result :Int
    if(dices[0] == dices[1] 
       && dices[0] == dices[2] 
       && dices[0] == dices[3] 
       && dices[0] == dices[4] ) {
       result = 15
    } else {
       result = 0
    }
 
    assertEquals(15, result)
}

或者换一种写法:

您将掷骰子添加到名为 dices 的变量中,但这是在您的测试中声明的,它不是您在 Dice 类中使用的变量,而是另一个列表。

您可以像这样修复您的测试:

class DiceTest {

private val dice = Dice()

@Before
fun init() {
    dice.firstDice = 1
    dice.secondDice = 1
    dice.thirdDice= 1
    dice.fourthDice = 1
    dice.fifthDice = 1

    dice.dices.add(dice.firstDice)
    dice.dices.add(dice.secondDice)
    dice.dices.add(dice.thirdDice)
    dice.dices.add(dice.fourthDice)
    dice.dices.add(dice.fifthDice)
}

@Test
fun checkingFiveOfAKind () {
    assertEquals(15, dice.winningCheck())
}

【讨论】:

    【解决方案2】:

    简单的答案是:

    而不是像这样添加骰子:

    dices.add(dice.firstDice)
    

    你需要像这样添加:

    dice.dices.add(dice.firstDice)
    

    winningCheck() 正在检查 Dice

    【讨论】:

    【解决方案3】:

    作为编码最佳实践的附注:

    另一种测试骰子类的方法是覆盖您尝试控制的部分(随机数生成器)。这样你就可以测试你的类的公共接口,而不是暴露字段进行测试。像这样的:

    interface NumberGenerator {
         fun generate() : Int
    }
    
    class RandomNumberGenerator : NumberGenerator {
        override fun generate() {
            return Random.nextInt(1,7)
        }
    }
    
    class Dice(private val numberGenerator: NumberGenerator = RandomNumberGenerator()) {
        
        private var firstDice = 1
        private var secondDice = 1
        private var thirdDice = 3
        private var fourthDice = 2
        private var fifthDice = 2
        private val dices: MutableList<Int> = ArrayList()
        
        fun throwDices() {
            firstDice = numberGenerator.generate()
            dices.add(firstDice)
            println("Eldobtad a kockákat, az első kocka értéke: $firstDice")
            secondDice = numberGenerator.generate()
            dices.add(secondDice)
            println("A második kocka értéke: $secondDice")
            thirdDice = numberGenerator.generate()
            dices.add(thirdDice)
            println("A harmadik kocka értéke: $thirdDice")
            fourthDice = numberGenerator.generate()
            dices.add(fourthDice)
            println("A negyedik kocka értéke: $fourthDice")
            fifthDice = numberGenerator.generate()
            dices.add(fifthDice)
            println("Az ötödik kocka értéke: $fifthDice")
            dices.sort()
            println(dices)
        }
        
        fun winningCheck() :Int {
            // Your winning check code here
        }
    }
    

    然后在你的测试中:

    class TestNumberGenerator(
        private val numbersToReturn: List<Int>,
    ) : NumberGenerator {
        private var count = 0
    
        override fun generate() {
            return numbersToReturn.get(count).also {
                if(count == numbersToReturn.size) count = 0 else count++
            }
        }
    }
    
    
    class DiceTest {
        
        @Test
        fun checkingFiveOfAKind () {
            val dice = Dice(TestNumberGenerator(listOf(1, 1, 1, 1, 1)))
    
            dice.throwDices()
    
            assertEquals(15, dice.winningCheck())
        }
    
    }
    

    TestNumberGenerator 仍然假设所有骰子都按顺序掷骰子,并且每个骰子只掷一次,但它适用于您当前的代码,并且它使您的测试更容易理解 :-)。

    【讨论】:

    • 我是 Kotlin 的新手。在 Kotlin 之前我学习了 Java,但我认为 Kotlin 是我要学习的语言。我试图通过比较骰子来检查是否获胜,但我认为更容易检查它何时在列表中排序。非常感谢您的帮助,我真的很感激!