<?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>DEV Community: Toni Petrina</title>
    <description>The latest articles on DEV Community by Toni Petrina (@tpetrina).</description>
    <link>https://dev.to/tpetrina</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%2F12066%2F1407815.jpeg</url>
      <title>DEV Community: Toni Petrina</title>
      <link>https://dev.to/tpetrina</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tpetrina"/>
    <language>en</language>
    <item>
      <title>Entity Component System in TypeScript</title>
      <dc:creator>Toni Petrina</dc:creator>
      <pubDate>Tue, 26 May 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/tpetrina/entity-component-system-in-typescript-ha6</link>
      <guid>https://dev.to/tpetrina/entity-component-system-in-typescript-ha6</guid>
      <description>&lt;p&gt;Games can be architected in different ways, but Entity Component System, also known as ECS, is one of the more popular ones. I won’t spend too much time explaining why one should pick ECS over OOP or any other style, there are better resources out there.&lt;/p&gt;

&lt;p&gt;In this series I will document my experience building ECS in TypeScript and why I did what I did.&lt;/p&gt;

&lt;p&gt;To begin, we need a &lt;code&gt;Component&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// All components must identify themselves.
type Component = {
  type: string;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entities are composed of components and merely identifiers. However, I want to start with something easier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Entity = {
  id: number;
  components: Component[];
};

let nextId = 1;
function createEntity(...components: Component[]) {
  return {
    id: nextId++,
    components,
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, so good.&lt;/p&gt;

&lt;p&gt;It’s important that components carry state and there should be no logic in either components or entities. So where is the logic? Inside &lt;code&gt;System&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;System will receive a list of entities and process them in some way. They should have no state and merely operate on components/entities. They can read them, update components, create or remove components or even whole entities.&lt;/p&gt;

&lt;p&gt;The simplest abstraction is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// something we need to supply every frame
// can be current time, current frame number, both or more
type TickInfo = number;

type System = {
  update: (tickInfo: TickInfo, entities: Entity[]) =&amp;gt; void;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it! Let’s build something with this!&lt;/p&gt;

&lt;h2&gt;
  
  
  An example
&lt;/h2&gt;

&lt;p&gt;The first useful component we can think of is position:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PositionComponent implements Component {
  type = 'position';
  constructor(public x: number, public y: number) {}
}

// easy way of creating position
const position = new PositionComponent(10, 10);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So how would we render it? Our game loop should be rather simple. Given a list of systems we call &lt;code&gt;update&lt;/code&gt; on every one of them per frame.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const systems: System[] = [];
const entities: Entity[] = [];

function render() {
  const now = new Date().getTime();

  systems.forEach((system) =&amp;gt; system.update(now, entities));

  requestAnimationFrame(render);
}

render();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s create a simple rendering system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createRenderSystem(): System {
  const canvas = document.createElement('canvas');
  document.body.appendChild(canvas);
  const ctx = canvas.getContext('2d');

  return {
    update: () =&amp;gt; {
      ctx.save();
      ctx.setTransform(1, 0, 0, 1, 0, 0);
      ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      ctx.restore();

      entities.forEach((e) =&amp;gt; {
        // so how do we get the rendering data
      });
    },
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So…given a list of entities we only care about a few select components. Let’s introduce a new helper function: &lt;code&gt;getComponent&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getComponent&amp;lt;T extends Component&amp;gt;(e: Entity, type: string) {
  return e.components.find((c) =&amp;gt; c.type === type) as T;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can finish our render system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;entities.forEach((e) =&amp;gt; {
  const p = getComponent(e);
  ctx.fillRect(p.x, p.y, 1, 1);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this code yields a black rectangle on screen. Nothing exciting yet.&lt;/p&gt;

&lt;p&gt;Source code for this code can be found at &lt;a href="https://github.com/tpetrina/ecs-ts-test/blob/master/examples/ecs1.ts"&gt;https://github.com/tpetrina/ecs-ts-test/blob/master/examples/ecs1.ts&lt;/a&gt; and live demo at &lt;a href="https://ecs-ts-test.netlify.app"&gt;https://ecs-ts-test.netlify.app&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I don't trust unit tests with mocks</title>
      <dc:creator>Toni Petrina</dc:creator>
      <pubDate>Fri, 22 May 2020 16:23:00 +0000</pubDate>
      <link>https://dev.to/tpetrina/i-don-t-trust-unit-tests-with-mocks-3j55</link>
      <guid>https://dev.to/tpetrina/i-don-t-trust-unit-tests-with-mocks-3j55</guid>
      <description>&lt;p&gt;Dave Farley asks why TDD hasn't conquered the world:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--uKbUwcee--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1182936980/Photo_1_normal.jpg" alt="Dave Farley profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Dave Farley
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @davefarley77
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Why hasn’t TDD taken over the world? Anyone have any ideas? 🤷‍♂️
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      17:15 PM - 21 May 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1263518668643725312" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1263518668643725312" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1263518668643725312" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;Besides the obvious, and correct, reasons like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;People don't know how to do write tests.&lt;/li&gt;
&lt;li&gt;People don't have enough time to practice testing.&lt;/li&gt;
&lt;li&gt;Most of the code we write is untestable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I find the following reason especially true for myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unit tests with heavy use of mocks are terrible and I don't trust them!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Some example
&lt;/h2&gt;

&lt;p&gt;TDD advocates unit tests should be written before the implementation. It is also considered that units refer to single methods. In modern C# Web applications these methods typically refer to &lt;em&gt;service methods&lt;/em&gt;. Typical service is stateless and various methods do not share anything but being part of the same class. The only reason we have service in C# is to use constructor based dependency injection in order to simplify dependencies. An example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IUserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IUserRepository&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IUserRepository&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userRepository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ChangeUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using constructor injection our &lt;em&gt;public&lt;/em&gt; interface is simpler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IUserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ChangeUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would argue that this kind of code is much easier to write and reason about. However, testing is deceptively easier. And in that deception the problem lies.&lt;/p&gt;

&lt;h2&gt;
  
  
  TDD...is impossible?
&lt;/h2&gt;

&lt;p&gt;Forget the above implementation and just focus on the method we need to test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ChangeUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How should we approach implementing this method using TDD? Once we test the obvious validation which just tests that the method throws, we need to test the happy path. Thus we start by creating our system under test (SUT):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;NewName__IsSaved&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"FAKE-ID"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"new-name"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sut&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Of&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IUserRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;());&lt;/span&gt;

  &lt;span class="c1"&gt;// Act&lt;/span&gt;
  &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ChangeUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Assert&lt;/span&gt;
  &lt;span class="c1"&gt;// ???&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above sample, mocking is done using &lt;a href="https://github.com/moq/moq4"&gt;Moq&lt;/a&gt;, but other libraries could be used as well.&lt;/p&gt;

&lt;p&gt;What matters is that it is extremely hard for a developer to correctly continue implementing this test. First of all, how do we verify correct behavior? How do we write that code &lt;em&gt;intuitively&lt;/em&gt;? What does it mean for this code to succeed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;NewName__IsSaved&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Arrange&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"FAKE-ID"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"new-name"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userRepoMock&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IUserRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;userRepoMock&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt;   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt;   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sut&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userRepoMock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="c1"&gt;// Act&lt;/span&gt;
   &lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ChangeUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Assert&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;userRepoMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Once&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Added lines are marked with &lt;code&gt;+&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ouch
&lt;/h2&gt;

&lt;p&gt;The first issue is the explosion in complexity of our arrange phase. The second problem is that &lt;em&gt;it is not obvious what to do withour prior knowledge of the implementation&lt;/em&gt;. This point cannot be stressed enough - for TDD to work it should be easy to write tests beforehand just by reasoning. And the above test cannot be written before the implementation - thus TDD won't help you.&lt;/p&gt;

&lt;p&gt;And that code is &lt;em&gt;typical&lt;/em&gt; in most applications.&lt;/p&gt;

&lt;p&gt;The code is testable, code coverage is high, some regressions are prevented...but personally, this style of coding and testing is ugly, nonintuitive, heavy, and not in the spirit of TDD.&lt;/p&gt;

&lt;p&gt;In fact, the test suite comprised of tests like that one often trigger memes where unit tests pass, but the system doesn't work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there a way out of here?
&lt;/h2&gt;

&lt;p&gt;Sure, use TDD to unit test pure methods with black box testing where the output is easy to test and comprehend just by looking at the input and method name.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you need to open the method to correctly mock stuff then you'll face issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some points to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For complex features use BDD testing on a higher level instead of focusing on individual methods like this.&lt;/li&gt;
&lt;li&gt;Mocking doesn't necessarily mean using a low-level mocking library - an in-memory DB &lt;em&gt;is a valid mock&lt;/em&gt;. If you are testing feature interaction, the database implementation is literally mocked away by using an in-memory representation. How DB works is not the point of those tests.&lt;/li&gt;
&lt;li&gt;Consider only mocking code you don't own - thus interior part of your module/assembly shouldn't be mocked away.&lt;/li&gt;
&lt;li&gt;Learn your tools - testing should be done and some proficiency of tools is required before knowing what and when to test.&lt;/li&gt;
&lt;li&gt;Learn the difference between state testing and property testing.&lt;/li&gt;
&lt;li&gt;Learn the difference between mockist and non-mockist schools of TDD. If you are learning about TDD, the not-so-subtle difference of these schools of thought is usually hidden from the text. This is extremely dangerous when paired with naive examples like testing &lt;code&gt;ICalculator.Add&lt;/code&gt; method which is a pure method and is extremely easy to TDD. Unlike the above example typical in most line of business applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TDD is an extremely powerful technique, but it is not a silver bullet. Practice and learn where it can be applied with ease for a big gain, and where it is just a hindrance and waste of time.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>testing</category>
      <category>tdd</category>
    </item>
  </channel>
</rss>
