<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Darren McLeod</title>
    <description>The latest articles on Forem by Darren McLeod (@tempuskg).</description>
    <link>https://forem.com/tempuskg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1431332%2F786797ea-e9e6-4f82-a655-f098e22fe714.jpeg</url>
      <title>Forem: Darren McLeod</title>
      <link>https://forem.com/tempuskg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tempuskg"/>
    <language>en</language>
    <item>
      <title>My Wife's Cognitive Challenge</title>
      <dc:creator>Darren McLeod</dc:creator>
      <pubDate>Fri, 31 Oct 2025 00:59:52 +0000</pubDate>
      <link>https://forem.com/tempuskg/my-wifes-cognitive-challenge-174h</link>
      <guid>https://forem.com/tempuskg/my-wifes-cognitive-challenge-174h</guid>
      <description>&lt;p&gt;My wife is a professional dog trainer and behaviorist. Being the tech geek that I am I coded and maintain her website &lt;a href="https://dogsden.ca" rel="noopener noreferrer"&gt;https://dogsden.ca&lt;/a&gt;. She recently developed a training system called &lt;a href="https://dogsden.ca/online/cognitivechallenges" rel="noopener noreferrer"&gt;Barbara Lloyd's Canine Cognitive Challenges&lt;/a&gt;, a framework that focuses on cognitive skill building for dogs rather than traditional command based training. It uses structured problem solving tasks to reveal how a dog processes information, forms strategies, and adapts to new situations. In other words, it trains the thinking system, not just the response pattern.&lt;/p&gt;

&lt;p&gt;Key outcomes of this cognitive approach include:&lt;/p&gt;

&lt;p&gt;• Stronger resilience and confidence in puppies and young dogs&lt;br&gt;
• Improved focus and decision making in adult dogs&lt;br&gt;
• Greater curiosity, autonomy, and emotional stability&lt;/p&gt;

&lt;p&gt;The program had great success in real world training, so she wanted to turn it into a scalable online course. I dutifully coded one up as a subsite under her &lt;a href="https://dogsden.ca" rel="noopener noreferrer"&gt;https://dogsden.ca&lt;/a&gt; site. Got it all working, users can register, buy the course and go through the challenges. Then she starts to promote it on Facebook and I get this in Messenger:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7r7tdpdvk468v0za5dem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7r7tdpdvk468v0za5dem.png" alt="Whenever I post a link to my cognitive challenges this is how it shows up, the link works, but the link doesn't look write https://dogsden.ca/online/cognitivechallenges - The Dog's Den Online http://dogsden.ca/online/cognitivechallenges DOGSDEN.CA IIS 10.0 Detailed Error - 404.19 Not Found Reply" width="400" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've started doing prompt driven development quite a lot lately and I threw &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=GPT-5+AI+model&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;GPT-5&lt;/a&gt; at it. GPT-5 is my goto because I have found it has only failed me a few times. It began iterating and claiming victory numerous times but when deployed the problem remained. Then it added a &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=web.config+file+explained&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;web.config&lt;/a&gt; and the whole site quit working. I backed everything out and decided to give GPT-5 a timeout and switched to &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=Claude+Sonnet+4.5+AI+model&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;Claude Sonnet 4.5&lt;/a&gt; my backup AI model which also has only failed me a few times. It tries a few things and none of them work either. &lt;br&gt;
Well alright then I guess I'll have to do this old school, and start googling for what is going on. What is going on is there are hundreds of reasons for &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=Facebook+link+debugger+tool&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;Facebook's link tool&lt;/a&gt; to fail. This is one very troublesome tool. Luckily they provided an online tool &lt;a href="https://developers.facebook.com/tools/debug/" rel="noopener noreferrer"&gt;https://developers.facebook.com/tools/debug/&lt;/a&gt; to try and figure out which of the hundreds of reasons why your link isn't working. &lt;/p&gt;

&lt;p&gt;So using the debugger link tool I verify that an existing page on &lt;a href="https://dogsden.ca/schedule.aspx" rel="noopener noreferrer"&gt;https://dogsden.ca/schedule.aspx&lt;/a&gt; works no problem. Thinking maybe it doesn't like my subsite under a main site I will just create a page at the main site level &lt;a href="https://dogsden.ca/cognitivechallenges.aspx" rel="noopener noreferrer"&gt;https://dogsden.ca/cognitivechallenges.aspx&lt;/a&gt; that points to the subsite. I get the AI to create one up for me and do a fair bit of back and forth to get it looking properly. Then go to test it in the debugger link tool and it doesn't work. I get the same &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=IIS+10.0+Error+404.19+Not+Found&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;IIS 10.0 Detailed Error - 404.19 - Not Found&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok now what? I had made the new page a lot different than the other pages so thought let's just start with a copy of schedule.aspx and then start adding changes to it to see what is breaking the link tool. I make schedule2.aspx and the debugger link tool gives the same IIS 10.0 Detailed Error - 404.19 - Not Found.&lt;/p&gt;

&lt;p&gt;Well there's your problem, but how do you fix it? Any new page doesn't work. I decide to try AI again. This time giving &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=Perplexity+AI+Research&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;Perplexity Research&lt;/a&gt; a go. I find Perplexity research to be very good at browsing the web and summarizing what it found. &lt;/p&gt;

&lt;p&gt;Perplexity Research said I did need to change my web.config. It's solution 1 was to clear &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=request+filtering+rules+web+config&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;request filtering rules&lt;/a&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
  &amp;lt;system.webServer&amp;gt;
    &amp;lt;security&amp;gt;
      &amp;lt;requestFiltering&amp;gt;
        &amp;lt;filteringRules&amp;gt;
          &amp;lt;clear /&amp;gt;
        &amp;lt;/filteringRules&amp;gt;
      &amp;lt;/requestFiltering&amp;gt;
    &amp;lt;/security&amp;gt;
  &amp;lt;/system.webServer&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solution 3 was a little less general and just targeted specific url's. I went with Solution 3 and was happily surprised it actually worked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
  &amp;lt;system.webServer&amp;gt;
    &amp;lt;security&amp;gt;
      &amp;lt;requestFiltering&amp;gt;
        &amp;lt;alwaysAllowedUrls&amp;gt;
          &amp;lt;add url="/schedule2.aspx" /&amp;gt;
        &amp;lt;/alwaysAllowedUrls&amp;gt;
      &amp;lt;/requestFiltering&amp;gt;
    &amp;lt;/security&amp;gt;
  &amp;lt;/system.webServer&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My wife's site is on a &lt;a href="https://www.google.com/search?ved=1t:260882&amp;amp;q=shared+hosting+limitations&amp;amp;bbid=5135016649671799184&amp;amp;bpid=1500157426962599151" rel="noopener noreferrer"&gt;shared hosting site&lt;/a&gt; and they must have implemented a filtering rule that only triggers on something Facebook adds when scraping a new url it's never seen before. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>seo</category>
    </item>
    <item>
      <title>Kanban and the Methodology With No Name</title>
      <dc:creator>Darren McLeod</dc:creator>
      <pubDate>Thu, 31 Jul 2025 17:21:49 +0000</pubDate>
      <link>https://forem.com/tempuskg/kanban-and-the-methodology-with-no-name-4b2f</link>
      <guid>https://forem.com/tempuskg/kanban-and-the-methodology-with-no-name-4b2f</guid>
      <description>&lt;p&gt;There is a software development methodology that uses a Kanban board, but it isn’t called Kanban because Kanban isn’t a methodology. It’s just a method, a board with columns and stickies to track work, which this guide says can be used with any methodology and is not a methodology in itself.&lt;/p&gt;

&lt;p&gt;So I call it the Methodology with No Name(MWNN), like Sergio Leone's character the Man with No Name. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkd7qy2xepz5l70d1pqlg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkd7qy2xepz5l70d1pqlg.jpg" alt="Clint Eastwood as the Man with No Name" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The MWNN is simple. You add a column on the Kanban board that is a prioritized list of work that is ready to start work on next. But the trick is that the column has a reverse WIP limit, where you make sure the number of stickies in the column never falls below the reverse WIP limit number. This way work is never stalled waiting for a sticky to be completely defined and ready to begin being worked on. &lt;/p&gt;

&lt;p&gt;That's it. You just do the work in the usual Kanban way respecting WIP limits of all the columns.&lt;/p&gt;

&lt;p&gt;With the MWNN there is no need for sprints and sprint planning where you try to guess how many stickies you can do in the sprint, and flagellate yourselves if you don't complete your guessed number of stickies or oddly even if you complete more stickies than you guessed.  I find this about as useful as medieval monks arguing about how many angels can do the Mambo No.5 on the head of a pin. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6qxliphjt1f15nuctj4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6qxliphjt1f15nuctj4.jpg" alt="The Bad character from Sergio Leone's westerns dancing on the head of a pin." width="171" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the MWNN you are free to pick and choose whichever processes you feel will help your team succeed. Like Tuco does to assemble his perfect gun. To me this extremely light weight methodology, of all the methodologies, best fits the agile manifesto's number one value "Individuals and interactions over processes and tools".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7lo4hagucz3p4ol5u7u.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7lo4hagucz3p4ol5u7u.gif" alt="Tuco assembles his perfect gun from multiple other guns." width="132" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kanban</category>
      <category>agile</category>
      <category>methodology</category>
      <category>mwnn</category>
    </item>
    <item>
      <title>Test Code</title>
      <dc:creator>Darren McLeod</dc:creator>
      <pubDate>Fri, 04 Jul 2025 12:41:45 +0000</pubDate>
      <link>https://forem.com/tempuskg/test-code-13op</link>
      <guid>https://forem.com/tempuskg/test-code-13op</guid>
      <description>&lt;p&gt;For a long time, when I first started writing tests, I felt so unproductive writing tests. I would try to write the test as fast as possible so I could move on to the "real" code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwx8qh15ncj7ekc8s2t8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwx8qh15ncj7ekc8s2t8.png" alt="Ornately carved support beam in Khiva, Uzebekistan" width="800" height="507"&gt;&lt;/a&gt;Then one day when a production deployment failed due to missing a simple test I realized the critical value of tests, and that good tests are in fact "real" code and they do deliver immense value. I began to see tests as "support beams" for the application that prevent it from collapsing.&lt;/p&gt;

&lt;p&gt;What are good tests? Good tests are ones that fail only when there is something really wrong. Like the logic was altered unintentionally by some change. Good tests don't depend on data that might change. Good tests happen when you have complete control of all the inputs. If your test is failing when nothing is wrong then make it top priority to fix it, or delete it. No test &amp;gt; not working test. These tests will make you no longer trust your test results and they will lose value. You need good dependable tests to be the &lt;strong&gt;support beams&lt;/strong&gt; of your application. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wzexi7xxxtycrb8wl4w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wzexi7xxxtycrb8wl4w.jpg" alt="Charlie Chaplin in his hobo character with a cute dog" width="772" height="1239"&gt;&lt;/a&gt;When you delete a test that is not working you have to make sure that there is still some test that covers the code. You can do this with a code coverage tool or do what's called the Poor man's code coverage. Break the code and see what tests failed. This technique is useful even when you have a code coverage tool. The code line may show as covered but the test may not be testing all possible outcomes. You can quickly verify if a test is hitting that outcome by breaking the code and seeing if a test fails appropriately.&lt;/p&gt;

&lt;p&gt;Another barrier I found that made me not want to write tests was an unstable environment. I was using this BDD tool that had a habit of spontaneously not working. I would go to write a new test and then end up spending an hour trying to get the tool to function and feel incredibly unproductive. This flakey framework syndrome is not worth any benefits they provide and I would recommend ditching them if you can. If you are forced to use it, document the time you spend getting the framework running again and let your manager know the cost of using the tool. &lt;/p&gt;

&lt;p&gt;If your test framework is slow replace it. Speed is critical. If your tests are slow you are not going to run them as often as you should. In .NET I have found NUnit and xUnit to be way faster than MSTest, especially with parameterized tests. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5lhhiz059m7a6y535nt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5lhhiz059m7a6y535nt.png" alt="Aluminum beams are used to shore up a ceiling in a basement" width="200" height="150"&gt;&lt;/a&gt;The final thing that made me not want to write tests was legacy code that had no tests and thus wasn't written to easily support writing unit tests. A lot of the times it was like the code was written purposely to make writing unit tests as hard as possible. This was tricky until I started using a "shoring" technique. In construction they will sometimes use a temporary support apparatus called "shoring" while they build in the long term support beams. In coding the "shoring" is a hard coded integration test that will likely fail in the future when the data changes or a service changes, just to use temporarily, to shore up the code while I safely refactor it to something that &lt;a href="https://www.darrenmcleod.com/2024/06/tomethodobject-refactoring.html" rel="noopener noreferrer"&gt;makes the test easy to write and then I can write the easy test&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>ToMethodObject Refactoring</title>
      <dc:creator>Darren McLeod</dc:creator>
      <pubDate>Wed, 18 Jun 2025 17:04:35 +0000</pubDate>
      <link>https://forem.com/tempuskg/tomethodobject-refactoring-28gd</link>
      <guid>https://forem.com/tempuskg/tomethodobject-refactoring-28gd</guid>
      <description>&lt;p&gt;I love refactoring code. To refactor code safely you need automated tests. Some code, especially code not written using Test Driven Development(TDD), make it difficult to write tests for the part of the code you are looking to change.&lt;/p&gt;

&lt;p&gt;Usually what you face are a class that has many dependencies, so in your test setup, you have to create all these dependencies to inject into the constructor even though many or perhaps all of these dependencies don't even have anything to do with the part of the code you are looking to change.&lt;/p&gt;

&lt;p&gt;Or the method that you want to write a change for is private and the calling public method has a bunch of dependencies which again many will not have anything to do with the part of the code you are looking to change.&lt;/p&gt;

&lt;p&gt;You are thinking: "If only this code was in a public method it would be so much easier to test". But you may have heard somewhere that changing the code just to make it easier to test is bad. &lt;/p&gt;

&lt;p&gt;This is a terrible line of thought that has cost me hours of coding. Forget you ever heard such a thing. If this is the first you have heard it, forget that I even said it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxg16ydyrawc01c28cs6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxg16ydyrawc01c28cs6m.png" alt="men in black clicking the mind wipe flash pen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testable code is good code, testable design is good design. Don't believe me? Watch this:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/fsvRXOADWnw"&gt;
  &lt;/iframe&gt;
 &lt;/p&gt;

&lt;p&gt;In the "Fixing Design with Tests" video above, Michael Feathers, the author of &lt;a href="https://www.amazon.ca/dp/0131177052?ref_=cm_sw_r_cp_ud_dp_ACWWWK19ZFT65PS8BXBZ" rel="noopener noreferrer"&gt;Working Effectively With Legacy Code&lt;/a&gt;, describes many different code issues that make tests hard to write and the design changes that will improve the design of the code and make tests easier to write.&lt;/p&gt;

&lt;p&gt;My new mantra, inspired by Kent Beck's &lt;a href="https://www.youtube.com/watch?v=yBEcq23OgB4&amp;amp;t=9s" rel="noopener noreferrer"&gt;Make the change easy ... make the easy change&lt;/a&gt;, is &lt;/p&gt;

&lt;h2&gt;
  
  
  Make the test easy to write. Write the easy test.
&lt;/h2&gt;

&lt;p&gt;A common pattern that came up when I started doing this, is a type of "Replace Method with Method Object" refactoring. &lt;/p&gt;

&lt;p&gt;What I would do is pull the code that I want to test into a static method or if it's in a private method then make the method static and then do the "Replace Method with Method Object" refactoring.&lt;/p&gt;

&lt;p&gt;Then it was easy to test the new Method Object class.&lt;/p&gt;

&lt;p&gt;I ended up doing this so often that I decided to create a Visual Studio Extension &lt;a href="https://marketplace.visualstudio.com/items?itemName=DarrenJMcLeod.tomethodobject" rel="noopener noreferrer"&gt;ToMethodObject&lt;/a&gt; that will take a static method and automatically create the Method Object class for me.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://marketplace.visualstudio.com/items?itemName=DarrenJMcLeod.tomethodobject" rel="noopener noreferrer"&gt;ToMethodObject&lt;/a&gt; extension uses an &lt;a href="https://en.wikipedia.org/wiki/Agent_noun" rel="noopener noreferrer"&gt;Agent Noun&lt;/a&gt; of the method name to come up with the name of the Method Object class. &lt;/p&gt;

&lt;p&gt;For example, say you wanted to make a change to how a friend is checked for in the &lt;strong&gt;TripService&lt;/strong&gt; class of the TripServiceKata:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsfhja2h6m051hufidrk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsfhja2h6m051hufidrk.png" alt="TripService class code with if(friend.Equals(logged User)) highlighted"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before doing this you would want to have this code covered by automated tests but to do so would result in problems with these 2 calls that are flagged as service calls by the kata:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxx4uxmn0n9tkkcqehcs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvxx4uxmn0n9tkkcqehcs.png" alt="arrows point to the GetLoggedUser and FindTripsByUser function calls"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of trying to mock out the service calls at this time, what we can do is pull out the friend check code here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falc9qrpwgxvdttlk2mw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falc9qrpwgxvdttlk2mw1.png" alt="highlighted the for each loop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And use the automated extract method refactoring to a static method like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sacoyyn396mrv830yfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sacoyyn396mrv830yfs.png" alt="for each loop refactored to a static FriendCheck method"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can refactor the &lt;strong&gt;FriendCheck&lt;/strong&gt; to a method object using my &lt;a href="https://marketplace.visualstudio.com/items?itemName=DarrenJMcLeod.tomethodobject" rel="noopener noreferrer"&gt;ToMethodObject&lt;/a&gt; automated refactoring:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdod1n564s9ybjjl87p8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdod1n564s9ybjjl87p8.png" alt="FriendCheck method being refactored to FriendChecker class"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This creates a new method object class called &lt;strong&gt;FriendChecker&lt;/strong&gt; that is easy to test as it has no tricky dependencies that aren't even needed for the code we want to change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zq021qh349c8zk721km.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2zq021qh349c8zk721km.png" alt="The new FriendChecker class with FriendCheck method"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The original method is automatically updated to call our new &lt;strong&gt;FriendChecker&lt;/strong&gt; method object class:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqlgke35pey0cx7sxs15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqlgke35pey0cx7sxs15.png" alt="Original code with call to create FriendChecker class and call the FriendCheck method"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can download my &lt;strong&gt;ToMethodObject&lt;/strong&gt; refactoring tool &lt;a href="https://marketplace.visualstudio.com/items?itemName=DarrenJMcLeod.tomethodobject" rel="noopener noreferrer"&gt;here&lt;/a&gt; and you too can start to &lt;strong&gt;"Make the test easy to write. Write the easy test!"&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>softwaredevelopment</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
