{"id":185,"date":"2011-02-19T08:00:00","date_gmt":"2011-02-19T08:00:00","guid":{"rendered":"https:\/\/pagan-gerbil.net\/?p=185"},"modified":"2011-02-19T08:00:00","modified_gmt":"2011-02-19T08:00:00","slug":"learning-unit-testing-ix-moving-on-with-movement","status":"publish","type":"post","link":"https:\/\/www.pagan-gerbil.net\/?p=185","title":{"rendered":"Learning Unit Testing IX &#8211; Moving On With Movement"},"content":{"rendered":"<p>Having gotten those knotty problems with world management, distances, directions, etc all out of the way I can finally move off of page 10. So what\u2019s next? Page 11! Hooray!<\/p>\n<p>It begins with a description of a charge move. A charge works like a run, at double-move rate, with the model (hopefully) ending up in contact with an enemy, or with a low wall that is also in contact with the enemy. The movement side of things should be fairly easy, but describing \u2018base contact\u2019 might be slightly more difficult.<\/p>\n<p>In the real game, a model\u2019s base is usually a circle 25mm in diameter. This is close enough to one inch to be treated as one of the arbitrary units I\u2019m using for movement and measurement, so a model can be described as having a width of 1. If I choose the location to describe the centre-point of a model\u2019s base, then \u2018base contact\u2019 would be a point equal to half the charger\u2019s width plus half the target\u2019s width, to allow for future models that may be bigger or smaller than a normal one (I\u2019m fondly thinking of Ogryns!)<\/p>\n<p>I started skirting around the issue slightly in the last post, but I need to seriously consider scenery and models as things with width and height, more than points on a virtual graph. The scenery will also need a different method of determining base contact, since it won\u2019t often have a circular base.<\/p>\n<p>It\u2019s taking me a while to work out exactly which direction (no pun intended) to go with this. A charge sounds exactly like a regular run move, except you can (and are expected to!) get within 8\u201d of an enemy model without stopping, and it declares that the model \u201cCan do nothing for the rest of the turn.\u201d To that end, I believe that only three new tests are needed, on a \u2018charge\u2019 method \u2013 one that makes sure a charging model can approach within 8\u201d of an enemy, one that checks that an \u2018isCharging\u2019 flag is set so that the model can\u2019t take any more actions this turn, and one that checks that that flag is removed at the beginning of a turn.<\/p>\n<p>The first test \u2013 that the model doesn\u2019t stop moving close to an enemy \u2013 is almost identical to the one that checks that it <em>does<\/em> stop moving close to an enemy, but with a different expected final position and no exception thrown.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Charge_CanGetWithin8InchesOfEnemy()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\nenemyModel.Location.X = 9;\nenemyModel.Location.Y = 0;\nenemyModel.Location.Z = 0;\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel });\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\ntestModel.Movement = 4;\ntestModel.Location.X = 0;\ntestModel.Location.Y = 0;\ntestModel.Location.Z = 0;\n<span style=\"color: blue\">bool <\/span>exceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\nmockObjectManager.Setup(item =&gt; item.GetDistanceBetween(testModel.Location, <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: blue\">float<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: blue\">float<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: blue\">float<\/span>&gt;())).Returns(8);\nmockObjectManager.Setup(item =&gt; item.GetPointOfIntersection(testModel.Location, <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">LocationPoint<\/span>&gt;(), enemyModel.Location, 8)).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(1, 0, 0));\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(testModel, enemyModel)).Returns(1);\ntestModel.Charge(8, 0, 0);\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">MovementException <\/span>ex)\n{\nexceptionThrown = <span style=\"color: blue\">true<\/span>;\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(exceptionThrown);\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(8, testModel.Location.X);\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(0, testModel.Location.Y);\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(0, testModel.Location.Z);\n}<\/pre>\n<p>The code to pass this test is extremely simple:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">private bool <\/span>_isCharging = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">public void <\/span>Charge(<span style=\"color: blue\">float <\/span>positionX, <span style=\"color: blue\">float <\/span>positionY, <span style=\"color: blue\">float <\/span>positionZ)\n{\n_isCharging = <span style=\"color: blue\">true<\/span>;\nMoveModel(positionX, positionY, positionZ);\n}<\/pre>\n<p>And a quick change to the ValidateMove method to check if the model is charging before validating the \u2018within 8\u201d of an enemy\u2019 rule:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">if <\/span>(<span style=\"color: blue\">this<\/span>.TotalDistanceMoved + distanceToPoint &gt; <span style=\"color: blue\">this<\/span>.Movement &amp;&amp; _isCharging == <span style=\"color: blue\">false<\/span>)<\/pre>\n<p>I almost feel silly for thinking it would be any harder than that, but then I was originally worrying about the base sizes, low wall restriction, etc, that is all part of \u2018being in base contact\u2019 \u2013 as far as Movement is concerned, it doesn\u2019t matter if the models are in base contact after a charge, only that a charge was attempted. The next test, then, checks that the flag is set:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Charge_SetsIsChargingFlag()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\ntestModel.Movement = 4;\ntestModel.Location.X = 0;\ntestModel.Location.Y = 0;\ntestModel.Location.Z = 0;\nmockObjectManager.Setup(item =&gt; item.GetDistanceBetween(testModel.Location, <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: blue\">float<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: blue\">float<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: blue\">float<\/span>&gt;())).Returns(8);\ntestModel.Charge(8, 0, 0);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(testModel.IsCharging);\n}<\/pre>\n<p>The code only needed to change the private _isCharging to a public IsCharging property, and again \u2013 straight into the pass. To make sure the NewTurn method resets the charging flag:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>NewTurn_SetsIsChargingToFalse()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\ntestModel.Movement = 4;\ntestModel.Charge(8, 0, 0);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(testModel.IsCharging);\ntestModel.NewTurn();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsCharging);\n}<\/pre>\n<p>Code to pass that test is just insultingly simple. At this time, I realised that the IsRunning flag might not have been set back to false at the beginning of a new turn \u2013 there\u2019s no test for it, so I\u2019ll add that in now.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>NewTurn_SetsIsRunningToFalse()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;());\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\ntestModel.Movement = 4;\ntestModel.MoveModel(8, 0, 0);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(testModel.IsRunning);\ntestModel.NewTurn();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsRunning);\n}<\/pre>\n<p>And as I predicted \u2013 it fails! The passing code should, again, be fairly easy to figure out. So I now have all the basics of charging, without the \u2018is in base contact\u2019 checks which will mostly be mathematical functions, and abstracted out without really implementing them (as I decided earlier).<\/p>\n<p>The next challenge is Hiding, then we can move away from page 11 \u2013 much faster than getting away from page 10 was, at any rate! As I see it, the following things are necessary to check for hiding:<\/p>\n<ul>\n<li>A model can choose to hide if it ends it\u2019s turn in \u2018reasonable\u2019 cover\n<li>A model can move about and stay hidden, as long as it doesn\u2019t leave the \u2018reasonable\u2019 cover.\n<li>A model cannot run or charge and hide in the same turn.\n<li>If an enemy model moves to a position it can see the hiding model, it ceases to be hidden.\n<li>A model ceases to be hidden if an enemy is within it\u2019s Initiative value in inches of the model. <\/li>\n<\/ul>\n<p>I will define \u2018reasonable\u2019 cover as being in at least 40% cover \u2013 this value could easily be tweaked later. I had decided while brainstorming before that line-of-sight shouldn\u2019t return a boolean value, rather a percentage of the target that is visible. In systems that can determine only \u2018visible\u2019 and \u2018not visible\u2019, the IObjectManager would obviously return 0 and 1 and nothing in between. More subtle systems would give a range of values, meaning that cover saves (when I get to shooting) will take account of partial cover, heavy cover, etc. The first test then will check line of sight from every enemy, to make sure that it is not more than 60% visible to any of them.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_SetsFlagIfInReasonableCover()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel });\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\n<span style=\"color: blue\">bool <\/span>exceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(0.5f);\ntestModel.Hide();\n}\n<span style=\"color: blue\">catch <\/span>(HidingException ex)\n{\nexceptionThrown = <span style=\"color: blue\">true<\/span>;\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(exceptionThrown);<br>    <span style=\"color: #2b91af\">Assert<\/span>.IsTrue(testModel.IsHiding);\n}<\/pre>\n<p>Code to pass this test:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public void <\/span>Hide()\n{\n<span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt; enemyModels = (<span style=\"color: blue\">from <\/span>models <span style=\"color: blue\">in this<\/span>._gameManager.Models\n<span style=\"color: blue\">where <\/span>models.Player != <span style=\"color: blue\">this<\/span>.Player\n&amp;&amp; <span style=\"color: blue\">this<\/span>._objectManager.GetLineOfSight(models, <span style=\"color: blue\">this<\/span>) &gt; 0.6\n<span style=\"color: blue\">select <\/span>models).ToList();\n<span style=\"color: blue\">if <\/span>(enemyModels.Count &gt; 0)\n{\n<span style=\"color: #2b91af\">HidingException <\/span>ex = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">HidingException<\/span>();\nex.EnemyModels = enemyModels;\n<span style=\"color: blue\">throw <\/span>ex;\n}\n<span style=\"color: blue\">else\n<\/span>{\n<span style=\"color: blue\">this<\/span>.IsHiding = <span style=\"color: blue\">true<\/span>;\n}\n}<\/pre>\n<p>Using some lovely LINQy goodness! The next test:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_ThrowsExceptionIfInSight()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Model <\/span>enemyModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;() { enemyModel });\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(2, mockGameManager.Object, mockObjectManager.Object);\n<span style=\"color: blue\">bool <\/span>exceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\nmockObjectManager.Setup(item =&gt; item.GetLineOfSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), <span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;())).Returns(1);\ntestModel.Hide();\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\nexceptionThrown = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">Assert<\/span>.AreEqual(enemyModel, ex.EnemyModels[0]);\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(exceptionThrown);\n}<\/pre>\n<p>Needs no modification. Maybe I went a bit too far with the code writing, since I knew what the test would be in advance? I played with the figures to make sure that the test fails when it should.<\/p>\n<p>The following tests should prevent the Hiding flag staying set when running or charging:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_RemoveHidingFlagWhenRunning()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;());\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\ntestModel.IsHiding = <span style=\"color: blue\">true<\/span>;\ntestModel.Movement = 4;\ntestModel.MoveModel(6, 0, 0);\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n}\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_RemoveHidingFlagWhenCharging()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;());\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\ntestModel.IsHiding = <span style=\"color: blue\">true<\/span>;\ntestModel.Movement = 4;\ntestModel.Charge(6, 0, 0);\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n}<\/pre>\n<p>The code for both these tests is simple \u2013 change MoveModel and Charge to look like:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public void <\/span>MoveModel(<span style=\"color: blue\">float <\/span>positionX, <span style=\"color: blue\">float <\/span>positionY, <span style=\"color: blue\">float <\/span>positionZ)\n{\n<span style=\"color: blue\">try\n<\/span>{\nValidateMove(<span style=\"color: blue\">ref <\/span>positionX, <span style=\"color: blue\">ref <\/span>positionY, <span style=\"color: blue\">ref <\/span>positionZ);\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">Exception <\/span>ex)\n{\n<span style=\"color: blue\">throw<\/span>;\n}\n<span style=\"color: blue\">finally\n<\/span>{\n<span style=\"color: blue\">this<\/span>.TotalDistanceMoved += GetDistanceFrom(positionX, positionY, positionZ);\n<span style=\"color: blue\">this<\/span>.Location.X = positionX;\n<span style=\"color: blue\">this<\/span>.Location.Y = positionY;\n<span style=\"color: blue\">this<\/span>.Location.Z = positionZ;\n<span style=\"color: blue\">if <\/span>(<span style=\"color: blue\">this<\/span>.TotalDistanceMoved &gt; <span style=\"color: blue\">this<\/span>.Movement)\n{\n<span style=\"color: blue\">this<\/span>.IsHiding = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">this<\/span>.IsRunning = <span style=\"color: blue\">true<\/span>;\n}\n}\n}\n<span style=\"color: blue\">public void <\/span>Charge(<span style=\"color: blue\">float <\/span>positionX, <span style=\"color: blue\">float <\/span>positionY, <span style=\"color: blue\">float <\/span>positionZ)\n{\nIsHiding = <span style=\"color: blue\">false<\/span>;\nIsCharging = <span style=\"color: blue\">true<\/span>;\nMoveModel(positionX, positionY, positionZ);\n}<\/pre>\n<p>The next two tests check that a model can\u2019t hide if it charged or ran this turn:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_CannotHideIfRanInSameTurn()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;());\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\ntestModel.IsRunning = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: blue\">bool <\/span>correctExceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\ntestModel.Hide();\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\ncorrectExceptionThrown = <span style=\"color: blue\">true<\/span>;\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(correctExceptionThrown);\n}\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>Hide_CannotHideIfChargedInSameTurn()\n{\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt; mockGameManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IGameManager<\/span>&gt;();\n<span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt; mockObjectManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Mock<\/span>&lt;<span style=\"color: #2b91af\">IObjectManager<\/span>&gt;();\nmockGameManager.Setup(item =&gt; item.Models).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;());\n<span style=\"color: #2b91af\">Model <\/span>testModel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, mockGameManager.Object, mockObjectManager.Object);\ntestModel.IsCharging = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: blue\">bool <\/span>correctExceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\ntestModel.Hide();\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">HidingException <\/span>ex)\n{\ncorrectExceptionThrown = <span style=\"color: blue\">true<\/span>;\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(testModel.IsHiding);\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(correctExceptionThrown);\n}<\/pre>\n<p>I\u2019m really liking how simple these tests are to pass at the moment. The code to solve both of those tests goes at the top of the Hide method, and is just a quick check:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">if <\/span>(<span style=\"color: blue\">this<\/span>.IsCharging || <span style=\"color: blue\">this<\/span>.IsRunning)\n{\n<span style=\"color: #2b91af\">HidingException <\/span>ex = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">HidingException<\/span>(<span style=\"color: #a31515\">\"Cannot hide if charged or ran this turn.\"<\/span>);\n<span style=\"color: blue\">throw <\/span>ex;\n}<\/pre>\n<p>This is getting a bit too long (I\u2019m thinking that 2000 words, including code, should be a maximum limit on these). I\u2019ll continue more Hiding tests next time!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Having gotten those knotty problems with world management, distances, directions, etc all out of the way I can finally move off of page 10. So what\u2019s next? Page 11! Hooray! It begins with a description of a charge move. A charge works like a run, at double-move rate, with the model (hopefully) ending up in &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.pagan-gerbil.net\/?p=185\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learning Unit Testing IX &#8211; Moving On With Movement&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[43,62,63,64],"series":[73],"_links":{"self":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/185"}],"collection":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=185"}],"version-history":[{"count":0,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/185\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=185"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=185"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=185"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=185"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}