F# and Unit Testing
August 20, 2013 Leave a comment
Consider this code snippet in F#
- module Board =
- let tiles = [|0 .. 39|]
- let random = System.Random()
- let communityChest x =
- let communityChestDraw = random.Next(1,17)
- if communityChestDraw = 1 then
- 0
- else if communityChestDraw = 2 then
- 10
- else
- x
I then went to create a unit test for the communityChest function when it hit me that I will get unpredictable behavior because I am getting a random number within the method body. I made this same mistake when I created my windows phone 7 game where there combat engine was using a Random.Next() result.
Basically, I am repeating my mistakes across two languages. The good news is that the solution is the same for both languages: I need to inject the result from Random.Next() into community chest.
- let communityChest x y =
- if y = 1 then
- 0
- else if y = 2 then
- 10
- else
- x
And then
- let move x y =
- let communityChestDraw = random.Next(1,17)
- if x + y > 39 then
- x + y – 40
- else if x + y = 30 then
- 10
- else if x + y = 2 then
- communityChest 2 communityChestDraw
- else if x + y = 7 then
- chance 7
- else if x + y = 17 then
- communityChest 2 communityChestDraw
- else if x + y = 22 then
- chance 22
- else if x + y = 33 then
- communityChest 2 communityChestDraw
- else if x + y = 36 then
- chance 36
- else
- x + y
The other nice thing is I found the bug that was, well, bugging me. The reason that 2 showed up the most was that I had copied and pasted 2 to be the results of all community chest runs. I then changed the code to reflect the actual position of community chest:
- let move x y =
- let communityChestDraw = random.Next(1,17)
- if x + y > 39 then
- x + y – 40
- else if x + y = 30 then
- 10
- else if x + y = 2 then
- communityChest 2 communityChestDraw
- else if x + y = 7 then
- chance 7
- else if x + y = 17 then
- communityChest 17 communityChestDraw
- else if x + y = 22 then
- chance 22
- else if x + y = 33 then
- communityChest 33 communityChestDraw
- else if x + y = 36 then
- chance 36
- else
- x + y
So now I can do my unit tests:
- [TestClass]
- public class SimulatorTests
- {
- [TestMethod]
- public void communityChestWithOne_ReturnsZero()
- {
- var result = Simulator.communityChest(2, 1);
- Assert.AreEqual(0, result);
- }
- [TestMethod]
- public void communityChestWithTwo_ReturnsTen()
- {
- var result = Simulator.communityChest(2, 2);
- Assert.AreEqual(10, result);
- }
- [TestMethod]
- public void communityChestWithThree_ReturnsTwo()
- {
- var result = Simulator.communityChest(2, 3);
- Assert.AreEqual(2, result);
- }
- }
And the tests run green:
I love being able to write C# tests and test F# code…