{"id":112,"date":"2010-11-04T12:54:00","date_gmt":"2010-11-04T12:54:00","guid":{"rendered":"https:\/\/pagan-gerbil.net\/?p=112"},"modified":"2010-11-04T12:54:00","modified_gmt":"2010-11-04T12:54:00","slug":"learning-unit-testing-iii-emergent-design","status":"publish","type":"post","link":"https:\/\/www.pagan-gerbil.net\/?p=112","title":{"rendered":"Learning Unit Testing III &#8211; Emergent Design"},"content":{"rendered":"<p>So having seen the answers on my own <a href=\"http:\/\/www.stackoverflow.com\" target=\"_blank\" rel=\"noopener\">StackOverflow<\/a> question on <a href=\"http:\/\/stackoverflow.com\/questions\/3494961\/how-do-you-design-complex-systems-with-tdd\" target=\"_blank\" rel=\"noopener\">TDD Design<\/a>, I\u2019ve decided to go ahead with the \u2018emergent design\u2019 crowd and see what happens. It appears that the refactoring and mid-stream redesigning is an integral part of the TDD process. It\u2019ll all, of course, be described here (the process might be a little bit stream-of-consciousness) as I go through my design decisions \u2018out loud\u2019).<\/p>\n<p>I got up to the end of page 9 last time, about to start on the Movement section. In keeping with the single responsibility principle, I\u2019ll be putting movement logic in it\u2019s own class. Movement happens in a strict order \u2013 all chargers are declared and moved first, then any compulsory moves are made, and finally \u2018everything else\u2019 movement. This would be represented in the MovementManager class as having an internal phase structure, just like the GameManager.<\/p>\n<p>The question is, where should this be called from? The decision to stop moving chargers and move onto the next sub-phase is a player choice, therefore a user interface trigger (just as IncrementPhase). It is not something that can be automated or inferred. Should the IncrementPhase method (and associated fields) be moved out into a TurnManager class which is owned by GameManager \u2013 GameManager can then expose valid actions based on what phase and whose turn it is. Would that even need to be moved out into another class \u2013 if I am deciding actions based on what the GameManager will expose to a user interface, the turn logic can remain in GameManager.<\/p>\n<p>Alternatively, the MovementManager can broadly restrict actions based on the properties of it\u2019s parent (GameManager) and regulate it\u2019s own, internal restrictions based on sub-phase and a variation of that logic. This seems like the simplest solution \u2013 I can raise a custom exception if a method is called on the MovementManager that is invalid (wrong sub-phase, or wrong phase entirely). Time for a new cl- uh, test class, obviously. Some of the tests can be cribbed from the existing GameManagerTests, but there\u2019s no real worry about whose turn it is.<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestClass<\/span>]\n<span style=\"color: blue\">public class <\/span><span style=\"color: #2b91af\">MovementManagerTests\n<\/span>{\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>IncrementSubPhase_RollsBackToMoveChargersAfterEverythingElse()\n{\n<span style=\"color: #2b91af\">MovementManager <\/span>movementManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MovementManager<\/span>();\nmovementManager.IncrementSubPhase(); <span style=\"color: green\">\/\/ Go to compulsory moves\n<\/span>movementManager.IncrementSubPhase(); <span style=\"color: green\">\/\/ Go to everything else\n<\/span>movementManager.IncrementSubPhase(); <span style=\"color: green\">\/\/ Go back to Move Chargers\n<\/span><span style=\"color: #2b91af\">Assert<\/span>.AreEqual(<span style=\"color: #2b91af\">MovementSubPhase<\/span>.MoveChargers, movementManager.CurrentSubPhase);\n}\n[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>IncrementSubPhase_MovesForwardSubPhase()\n{\n<span style=\"color: #2b91af\">MovementManager <\/span>movementManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MovementManager<\/span>();\n<span style=\"color: #2b91af\">MovementSubPhase <\/span>firstPhase = movementManager.CurrentSubPhase;\nmovementManager.IncrementSubPhase();\n<span style=\"color: #2b91af\">MovementSubPhase <\/span>secondPhase = movementManager.CurrentSubPhase;\n<span style=\"color: #2b91af\">Assert<\/span>.AreNotEqual(firstPhase, secondPhase);\n}\n}<\/pre>\n<p>As expected, after resolving build errors (new class, property and method stubs) the two tests fail. And with the barest minimum of code:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">public class <\/span><span style=\"color: #2b91af\">MovementManager\n<\/span>{\n<span style=\"color: blue\">public <\/span><span style=\"color: #2b91af\">MovementSubPhase <\/span>CurrentSubPhase { <span style=\"color: blue\">get<\/span>; <span style=\"color: blue\">private set<\/span>; }\n<span style=\"color: blue\">public void <\/span>IncrementSubPhase()\n{\n<span style=\"color: blue\">if <\/span>(CurrentSubPhase == <span style=\"color: #2b91af\">MovementSubPhase<\/span>.EverythingElse)\n{\nCurrentSubPhase = <span style=\"color: #2b91af\">MovementSubPhase<\/span>.MoveChargers;\n}\n<span style=\"color: blue\">else\n<\/span>{\nCurrentSubPhase++;\n}\n}\n}<\/pre>\n<p>It all passes. Next up, there needs to be a way of preventing the Movement sub-phase from advancing when it is not the Movement phase at all. The expected behaviour for this should be a custom exception to be thrown, and dealt with elsewhere (presumably, the hypothetical UI). To fool it that it is not the Movement phase, it needs to have a reference to the GameManager \u2013 passed in as a constructor parameter to the MovementManager. The GameManager passed in for this test also needs to be mocked, so it will need to be given a public interface. One quick mocking later:<\/p>\n<pre class=\"code\">[<span style=\"color: #2b91af\">TestMethod<\/span>]\n<span style=\"color: blue\">public void <\/span>IncrementSubPhase_ThrowsExceptionIfNotMovementPhase()\n{\n<span style=\"color: blue\">bool <\/span>correctExceptionThrown = <span style=\"color: blue\">false<\/span>;\n<span style=\"color: blue\">try\n<\/span>{\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.CurrentPhase).Returns(<span style=\"color: #2b91af\">TurnPhase<\/span>.Shooting);\n<span style=\"color: #2b91af\">MovementManager <\/span>movementManager = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">MovementManager<\/span>(mockGameManager.Object);\nmovementManager.IncrementSubPhase();\n}\n<span style=\"color: blue\">catch <\/span>(<span style=\"color: #2b91af\">WrongPhaseException <\/span>ex)\n{\ncorrectExceptionThrown = <span style=\"color: blue\">true<\/span>;\n}\n<span style=\"color: #2b91af\">Assert<\/span>.IsTrue(correctExceptionThrown);\n}<\/pre>\n<p>Which is passed by:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">private void <\/span>ValidatePhase()\n{\n<span style=\"color: blue\">if <\/span>(_gameManager.CurrentPhase != <span style=\"color: #2b91af\">TurnPhase<\/span>.Movement)\n{\n<span style=\"color: blue\">throw new <\/span><span style=\"color: #2b91af\">WrongPhaseException<\/span>(<span style=\"color: #a31515\">\"Cannot perform Movement actions in the \" <\/span>+ _gameManager.CurrentPhase.ToString() + <span style=\"color: #a31515\">\" phase.\"<\/span>);\n}\n}<\/pre>\n<p>And calling that at the beginning of the IncrementSubPhase method.<\/p>\n<p>Now it\u2019s time to make some changes to the (as yet unused) Model class. Now it starts to get into things in a bit more of a distinct rule structure \u2013 the next line states that \u2018models can move up to their move rate in inches in any direction\u2019. I\u2019m deciding that \u2018inches\u2019 refers to an arbitrary (and divisible) number, so a decimal will serve very well to decide how far they\u2019ve moved, and how far they can move. The movement manager can either take in a co-ordinate to specify the target position, and change the model\u2019s position to as far as it can go towards that point, or take in a distance and direction and move the model as specified.<\/p>\n<p>It\u2019ll probably be easier to sort out the distance and direction at the moment \u2013 those calculations will need to be made in the code that calls the MovementManager \u2013 though at some future point, these could be made into helper methods on the MovementManager. To work out where the model\u2019s new position is, we need diagrams \u2013 this will have to wait until the next post!<\/p>\n<p><em>This has been a nice long post that gets about halfway through page 10. I\u2019m still not sure I\u2019m allowing the design to emerge \u2013 I am, for example, thinking a few tests ahead of where I am \u2013 but at this stage, I\u2019ve not (consciously) made a decision about design based on that forewarning, only on the basis of \u2018I want Movement code separate from Game Manager code). This is more to do with the single responsibility principle than some master design drawn upfront.<\/em><\/p>\n<p><em>This is a learning project I am documenting in order to teach myself TDD and unit testing \u2013 as I publish this, I have already written many parts in advance but I want to know what I\u2019m doing wrong! If you see improvements or corrections, either to the code or the process, please leave a comment and let me know! Introduction to this project can be found <a href=\"http:\/\/pagan-gerbil.net\/blog\/post.aspx?id=dfe72ad8-e4e9-48b4-ada3-6247abb5aa71\">here<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>So having seen the answers on my own StackOverflow question on TDD Design, I\u2019ve decided to go ahead with the \u2018emergent design\u2019 crowd and see what happens. It appears that the refactoring and mid-stream redesigning is an integral part of the TDD process. It\u2019ll all, of course, be described here (the process might be a &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.pagan-gerbil.net\/?p=112\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learning Unit Testing III &#8211; Emergent Design&#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\/112"}],"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=112"}],"version-history":[{"count":0,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=\/wp\/v2\/posts\/112\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=112"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.pagan-gerbil.net\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}