Reputation: 129
I write a program in Kotlin. The program is working fine, but I only test the function with running the program. I think I know what the problem is, but I don't know, how to modiy the test. Thanks in advance!
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
}
}
This is the class, I want to test, and here is the testing code:
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())
}
And here is the error code:
Upvotes: 0
Views: 410
Reputation: 76476
As a coding best practice side note:
Another way to test your dice class, would be to override the part you are trying to control (the random number generator). That way you can test the public interface of your class, instead of exposing the fields for testing. Something like this:
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
}
}
Then in your tests:
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())
}
}
The TestNumberGenerator
still assumes that all dice are rolled in order and only once each, but it'll work with your current code, and it makes your test much more understandable :-).
Upvotes: 1
Reputation: 21551
The simple answer is:
instead of adding dices like this:
dices.add(dice.firstDice)
you need to add like this:
dice.dices.add(dice.firstDice)
As winningCheck()
is checking inside the Dice
class
Upvotes: 1
Reputation: 76476
I think your example could be simplified to ask, why does't this code work:
@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)
}
But this code does work:
@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)
}
Or written another way:
You are adding your dice rolls to a variable called dices
but this is a declared in your test, it is not the variable you are using inside your Dice
class, that is another List.
You may be able to fix your test like this:
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())
}
Upvotes: 1