{"id":197,"date":"2011-04-21T14:15:00","date_gmt":"2011-04-21T13:15:00","guid":{"rendered":"https:\/\/pagan-gerbil.net\/?p=197"},"modified":"2011-04-21T14:15:00","modified_gmt":"2011-04-21T13:15:00","slug":"learning-unit-testing-xi-difficult-terrain-is-difficult","status":"publish","type":"post","link":"https:\/\/www.pagan-gerbil.net\/?p=197","title":{"rendered":"Learning Unit Testing XI &#8211; Difficult Terrain Is Difficult"},"content":{"rendered":"<p>As the title clearly states, difficult terrain is going to be hard. It will involve a replacement of the \u2018get distance\u2019 code that takes into account that strict distances are not the same as movement distances \u2013 the idea that four inches of distance may cost five, six or more inches of movement (which is what counts for running, charging, and moving in general).<\/p>\n<p>Because of this difficulty, my current inability to devise a solution, and my need to get moving on other things immediately (time on this project is limited, and I would rather move on than get stuck in design hell that maybe I should have sorted out sooner) I will be abandoning the Movement phase for the infinitely more interesting Shooting phase. It actually looks slightly easier, but I\u2019m sure that\u2019ll be remedied when I get to the rules for weapons and skills.<\/p>\n<p>Unlike movement, which started to bog down the Model class, I\u2019m going to try and keep all shooting related code in the shooting manager. Again, having an inkling of what the skills and weapons rules are going to do later, I believe this will make things a lot easier.<\/p>\n<p>The first thing written down is defining who can shoot \u2013 Any model can shoot as long as it\u2019s armed with a missile weapon, is not in hand-to-hand combat, can see a target, didn\u2019t run or charge and is not hiding. This seems like a sensible thing to write a checking method for, and a little raft of tests. Time for a new test class, and also (finally) a test helper.<\/p>\n<pre class=\"code\"><span style=\"color: blue\">class <\/span><span style=\"color: #2b91af\">TestHelper\n<\/span>{\n<span style=\"color: blue\">public static <\/span><span style=\"color: #2b91af\">IGameManager <\/span>GetMockGameManager(<span style=\"color: #2b91af\">IModel <\/span>testModel, <span style=\"color: #2b91af\">IObjectManager <\/span>objectManager, <span style=\"color: blue\">int <\/span>numberOfEnemies, <span style=\"color: blue\">int <\/span>numberOfAllies)\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\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt; modelList = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;();\nmodelList.Add(testModel);\n<span style=\"color: blue\">for <\/span>(<span style=\"color: blue\">int <\/span>i = 0; i &lt; numberOfAllies; i++)\n{\nmodelList.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(testModel.Player, mockGameManager.Object, objectManager));\n}\n<span style=\"color: blue\">for <\/span>(<span style=\"color: blue\">int <\/span>i = 0; i &lt; numberOfEnemies; i++)\n{\nmodelList.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(testModel.Player + 1, mockGameManager.Object, objectManager));\n}\nmockGameManager.Setup(item =&gt; item.Models).Returns(modelList);\n<span style=\"color: blue\">return <\/span>mockGameManager.Object;\n}\n}<\/pre>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestClass<\/span>]\n<span style=\"color: blue\">public class <\/span><span style=\"color: #2b91af\">ShootingManagerTests\n<\/span>{\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsTrue_IfEverythingCorrect()\n{\n<span style=\"color: #2b91af\">Model <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\n<span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(shootingTest.CanShoot(model));\n}\n}<\/pre>\n<p>Right, a lot of \u2018generate class\u2019 and \u2018generate stub\u2019 later (the ctrl+. shortcut is my friend) and the library compiles again. I intend for all missile weapons (that need special functionality not covered by the basic rules) to inherit from MissileWeapon, which ought to cover the majority of things. Weapons is a list of IWeapon (implemented by MissileWeapon), Direction is just an integer describing the angle the model faces (assuming a top-down view), and ShootingManager is quite an empty class at the moment. Following TDD pretty strictly, to pass this test it becomes:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public class <\/span><span style=\"color: #2b91af\">ShootingManager\n<\/span>{\n<span style=\"color: blue\">public bool <\/span>CanShoot(<span style=\"color: #2b91af\">Model <\/span>model)\n{\n<span style=\"color: blue\">bool <\/span>canShoot = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: blue\">return <\/span>canShoot;\n}\n}<\/pre>\n<p>But of course, that\u2019s not quite right. Here\u2019s a few more tests.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfRunning()\n{\n<span style=\"color: #2b91af\">Model <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\n<span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfCharging()\n{\n<span style=\"color: #2b91af\">Model <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\n<span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">true<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfHiding()\n{\n<span style=\"color: #2b91af\">Model <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\n<span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">true<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}<\/pre>\n<p>And what do all those lines of code need to make them pass?<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public bool <\/span>CanShoot(<span style=\"color: #2b91af\">Model <\/span>model)\n{\n<span style=\"color: blue\">bool <\/span>canShoot = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: blue\">if <\/span>(model.IsRunning == <span style=\"color: blue\">true <\/span>|| model.IsHiding == <span style=\"color: blue\">true <\/span>|| model.IsCharging == <span style=\"color: blue\">true<\/span>)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">return <\/span>canShoot;\n}<\/pre>\n<p>It\u2019s almost insulting. The next one should be a bit more of a challenge:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfNoMissileWeapon()\n{\n<span style=\"color: #2b91af\">Model <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\n<span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}<\/pre>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfOnlyMeleeWeapons()\n{\n<span style=\"color: #2b91af\">Model <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MeleeWeapon<\/span>());\n<span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}<\/pre>\n<p>And these are solved by:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public bool <\/span>CanShoot(<span style=\"color: #2b91af\">Model <\/span>model)\n{\n<span style=\"color: blue\">bool <\/span>canShoot = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: blue\">if <\/span>(model.IsRunning == <span style=\"color: blue\">true <\/span>|| model.IsHiding == <span style=\"color: blue\">true <\/span>|| model.IsCharging == <span style=\"color: blue\">true<\/span>)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">if <\/span>(model.Weapons.Where(item =&gt; (item <span style=\"color: blue\">as <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>) != <span style=\"color: blue\">null<\/span>).Count() == 0)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">return <\/span>canShoot;\n}<\/pre>\n<p>Linq makes things a little bit too easy these days&#8230; The next test checks if the model can see an opponent:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfNoEnemyInSight()\n{\n<span style=\"color: #2b91af\">Model <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\n<span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 0;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}<\/pre>\n<p>As expected, it fails. The only difference to the original \u2018everything is fine\u2019 test case is the direction that the model is facing \u2013 a model can only see in a 90 degree arc to it\u2019s front, so by turning it completely around it should be unable to see the enemy properly. The calculations on the abstract ObjectManager should reflect this, so an extra method in ObjectManager that is exposed (slightly) through Model will help out.<\/p>\n<p>First off \u2013 a lot of tests break. This is because the models have been set up with null object managers, which obviously throw exceptions when the call to check them for models in sight occurs. In refactoring to get the first test (pass if all clear) passing, references and parameters were shifted from Model to IModel, things were added to IModel,and in general a bit of housekeeping took place. Here is the new \u2018all clear\u2019 test:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsTrue_IfEverythingCorrect()\n{\n<span style=\"color: #2b91af\">IModel <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(0, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\n<span style=\"color: #2b91af\">IGameManager <\/span>gameManager = <span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\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;();\nmockObjectManager.Setup(item =&gt; item.GetModelsInSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), gameManager.Models, 90)).Returns(gameManager.Models);\nmodel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, gameManager, mockObjectManager.Object);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(shootingTest.CanShoot(model));\n}<\/pre>\n<p>With similar \u2018setup\u2019 code to the subsequent tests to get them all passing. The improved \u2018new\u2019 test:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfNoEnemyInSight()\n{\n<span style=\"color: #2b91af\">IModel <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(0, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\n<span style=\"color: #2b91af\">IGameManager <\/span>gameManager = <span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\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;();\nmockObjectManager.Setup(item =&gt; item.GetModelsInSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), gameManager.Models, 90)).Returns(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;());\nmodel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, gameManager, mockObjectManager.Object);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 0;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}<\/pre>\n<p>And finally, the code to pass it:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public bool <\/span>CanShoot(<span style=\"color: #2b91af\">IModel <\/span>model)\n{\n<span style=\"color: blue\">bool <\/span>canShoot = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: blue\">if <\/span>(model.IsRunning == <span style=\"color: blue\">true <\/span>|| model.IsHiding == <span style=\"color: blue\">true <\/span>|| model.IsCharging == <span style=\"color: blue\">true<\/span>)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">if <\/span>(model.Weapons.Where(item =&gt; (item <span style=\"color: blue\">as <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>) != <span style=\"color: blue\">null<\/span>).Count() == 0)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">if <\/span>((<span style=\"color: blue\">from <\/span>target <span style=\"color: blue\">in <\/span>model.GetModelsInSight(90)\n<span style=\"color: blue\">where <\/span>target.Player != model.Player\n<span style=\"color: blue\">select <\/span>target).Count() == 0)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">return <\/span>canShoot;\n}<\/pre>\n<p>With one small addition to the Model class:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt; GetModelsInSight(<span style=\"color: blue\">int <\/span>angleOfSight)\n{\n<span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt; modelsInSight = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;();\nmodelsInSight = _objectManager.GetModelsInSight(<span style=\"color: blue\">this<\/span>, _gameManager.Models, angleOfSight);\n<span style=\"color: blue\">return <\/span>modelsInSight;\n}<\/pre>\n<p>Finally, one more test and the \u2018who can shoot\u2019 question is completely answered. Models cannot shoot if they\u2019re already in hand-to-hand combat. A simple boolean property (the exact circumstances of being able to set it will be complicated, but that\u2019s a problem for later) on the Model and IModel, adding it as an explicit \u2018false\u2019 parameter in the other CanShoot tests, and it\u2019s own test case:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>CanShoot_ReturnsFalse_IfModelInHandToHandCombat()\n{\n<span style=\"color: #2b91af\">IModel <\/span>model = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(0, <span style=\"color: blue\">null<\/span>, <span style=\"color: blue\">null<\/span>);\n<span style=\"color: #2b91af\">IGameManager <\/span>gameManager = <span style=\"color: #2b91af\">TestHelper<\/span>.GetMockGameManager(model, <span style=\"color: blue\">null<\/span>, 1, 0);\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;();\nmockObjectManager.Setup(item =&gt; item.GetModelsInSight(<span style=\"color: #2b91af\">It<\/span>.IsAny&lt;<span style=\"color: #2b91af\">IModel<\/span>&gt;(), gameManager.Models, 90)).Returns(gameManager.Models);\nmodel = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Model<\/span>(1, gameManager, mockObjectManager.Object);\nmodel.Weapons.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>());\nmodel.Location = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">LocationPoint<\/span>(0, 1, 0);\nmodel.Direction = 180;\nmodel.IsCharging = <span style=\"color: blue\">false<\/span>;\nmodel.IsHiding = <span style=\"color: blue\">false<\/span>;\nmodel.IsRunning = <span style=\"color: blue\">false<\/span>;\nmodel.IsInHandToHandCombat = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: #2b91af\">ShootingManager <\/span>shootingTest = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ShootingManager<\/span>();\n<span style=\"color: #2b91af\">Assert<\/span>.IsFalse(shootingTest.CanShoot(model));\n}<\/pre>\n<p>And the complete CanShoot code to pass it:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public bool <\/span>CanShoot(<span style=\"color: #2b91af\">IModel <\/span>model)\n{\n<span style=\"color: blue\">bool <\/span>canShoot = <span style=\"color: blue\">true<\/span>;\n<span style=\"color: blue\">if <\/span>(model.IsRunning == <span style=\"color: blue\">true <\/span>|| model.IsHiding == <span style=\"color: blue\">true <\/span>|| model.IsCharging == <span style=\"color: blue\">true <\/span>|| model.IsInHandToHandCombat == <span style=\"color: blue\">true<\/span>)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">if <\/span>(model.Weapons.Where(item =&gt; (item <span style=\"color: blue\">as <\/span><span style=\"color: #2b91af\">MissileWeapon<\/span>) != <span style=\"color: blue\">null<\/span>).Count() == 0)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">if <\/span>((<span style=\"color: blue\">from <\/span>target <span style=\"color: blue\">in <\/span>model.GetModelsInSight(90)\n<span style=\"color: blue\">where <\/span>target.Player != model.Player\n<span style=\"color: blue\">select <\/span>target).Count() == 0)\n{\ncanShoot = <span style=\"color: blue\">false<\/span>;\n}\n<span style=\"color: blue\">return <\/span>canShoot;\n}<\/pre>\n<p>And it leaves me at a good point to finish off for this section. The next section will be the Closest Target rules, which I\u2019ve already given some thought to \u2013 but my word count here is already over 1500, so it\u2019s probably best to clock off!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As the title clearly states, difficult terrain is going to be hard. It will involve a replacement of the \u2018get distance\u2019 code that takes into account that strict distances are not the same as movement distances \u2013 the idea that four inches of distance may cost five, six or more inches of movement (which is &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.pagan-gerbil.net\/?p=197\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learning Unit Testing XI &#8211; Difficult Terrain Is Difficult&#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\/197"}],"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=197"}],"version-history":[{"count":0,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/197\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=197"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}