<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Ben Gilroy on Medium]]></title>
        <description><![CDATA[Stories by Ben Gilroy on Medium]]></description>
        <link>https://medium.com/@bengilroy?source=rss-7a55141e3bc8------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*DXhrp2ja_-lV-pDOswnaJg.jpeg</url>
            <title>Stories by Ben Gilroy on Medium</title>
            <link>https://medium.com/@bengilroy?source=rss-7a55141e3bc8------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 13 Jul 2026 09:23:38 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@bengilroy/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Using Array to Improve your Mocks in Unit Tests (iOS & Swift)]]></title>
            <link>https://medium.com/kinandcartacreated/using-array-to-improve-your-mocks-in-unit-tests-ios-swift-f8c343c80d21?source=rss-7a55141e3bc8------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8c343c80d21</guid>
            <category><![CDATA[engineering]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[testing]]></category>
            <dc:creator><![CDATA[Ben Gilroy]]></dc:creator>
            <pubDate>Tue, 05 May 2020 15:47:20 GMT</pubDate>
            <atom:updated>2020-05-05T16:08:44.089Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lms5qctM0HqOFBShDyzzIg.jpeg" /></figure><h3>Improving your Unit Test Mocks with Arrays (iOS &amp; Swift)</h3><p>In this post, I’m going to show how you can leverage arrays in your mocks to write better quality and more readable unit tests that might help you catch bugs in your code that you didn’t even know existed.</p><h3>What are unit tests and mocks?</h3><p>Although I’m not going to cover in detail what mocks and unit tests are, it’s often useful to start with a quick zoom out.</p><h4>Unit Testing</h4><p>Unit testing is a way in which we can test the behaviour and functionality of individual chunks of code.</p><p>For example, let’s say we have a Calculator object:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7f173138f5d80df4b329a34b8b03e7ef/href">https://medium.com/media/7f173138f5d80df4b329a34b8b03e7ef/href</a></iframe><p>We might want to test that its multiply function returns the correct result by writing the following test:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6ab8dbf8a2b52cbd8f45260a338d0f63/href">https://medium.com/media/6ab8dbf8a2b52cbd8f45260a338d0f63/href</a></iframe><h4>Mocks</h4><p>In reality, we’re often dealing with objects that have a lot more complexity and are therefore more difficult to test. Some objects might even have dependencies such as a network service that makes API calls, or perhaps a storage service that saves data to the user’s device.</p><p>To test these objects, we can inject ‘mocks’ of these dependencies which we can control in our tests to make sure our object behaves as expected. For example, we might inject a mock URLSession into a network service to ensure that the service maps to the correct success or failure result for various HTTP status codes that we tell our mock to return.</p><p>We can also use mocks to check that an object calls methods of other objects correctly. For example, we might have a view model that send an analytics event when a user signs out.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/421940bedccd5f5148e1b663c2796b6a/href">https://medium.com/media/421940bedccd5f5148e1b663c2796b6a/href</a></iframe><p>Now we’ve briefly covered what unit tests and mocks are, let’s jump into an example project where we can look at different ways we can write our mocks in unit tests to verify the behaviour of our code.</p><h3>Our Example Project</h3><p>In the <a href="https://github.com/bengilroy/MocksExample">example project</a> for this post, you will find a single MessageViewController following the Model-View-Presenter (MVP) architecture pattern with a button that says ‘Fetch message’.</p><p>Here’s what happens when you tap the button:</p><figure><img alt="Tapping fetch message shows loading spinner and then “Hello, world!”" src="https://cdn-images-1.medium.com/max/552/1*KGZGgg8iqgDYxxlgtV-Ybw.gif" /></figure><p>Let’s take a look at what is happening under the hood when we tap the fetch message button:</p><p>1. The MessageViewController tells the MessagePresenter that the fetch message button was tapped.<br>2. The MessagePresenter then tells the view to show the loading state, and calls an asynchronous fetchMessage function on the MessageService.<br>3. The MessageService then calls a completion handler with a Result&lt;String, Error&gt; which provides the message if successful, or an error if it failed.<br>4. The MessagePresenter then tells the view to update with fetched message (or error message), hide the loading state, and then show the message.</p><p>The main logic which handles the above is in the MessagePresenter:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dc70cd16c22f733499e5266b40add967/href">https://medium.com/media/dc70cd16c22f733499e5266b40add967/href</a></iframe><p>Let’s explore how we could test the above code to ensure everything is working as expected.</p><h3>Testing using Bool flags</h3><p>One way we can test the above function is to use a mock view which conforms to the MessageView protocol with a series of Bool flags that keep track of which functions are called. This might look something like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/55b6ecd877c555566ddda191481cf189/href">https://medium.com/media/55b6ecd877c555566ddda191481cf189/href</a></iframe><p>Then, in our tests we can set up our mock service with success or failure, call fetchMessageButtonTapped() on the presenter, and assert that the correct functions get called, like so:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/12929dbdaf0ad36208d59e8561776417/href">https://medium.com/media/12929dbdaf0ad36208d59e8561776417/href</a></iframe><p>Great! Now we’ve tested all the correct functions get called and our test coverage is at 100% for our MessagePresenter class.</p><p>However, test <em>coverage</em> does not necessarily indicate good test <em>quality</em>.</p><p>Let’s look at an example. If we add an extra call to view?.showLoading() at the end of the fetchMessage() function (as below) then our tests still pass, but now the loading indicator is still showing even after the message has been shown which is not what we want.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/936a83516065f1a8b6229512783bc5a9/href">https://medium.com/media/936a83516065f1a8b6229512783bc5a9/href</a></iframe><figure><img alt="Tapping fetch message shows loading spinner and then “Hello, world!” although loading spinner does not disappear" src="https://cdn-images-1.medium.com/max/552/1*qKqwzwgPPm5JVxxunUOqdw.gif" /></figure><p>In order to catch this type of bug in our unit tests, let’s take a look at how we can use call counts in our mocks.</p><h3>Testing using call counts</h3><p>To make sure that each function is only called the correct number of times, we can update our mock to use call counters which will increment each time the function is called.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5c7cc6f7488a96935b6ea8ce94c466d7/href">https://medium.com/media/5c7cc6f7488a96935b6ea8ce94c466d7/href</a></iframe><p>We can then update our tests to check the call count instead of checking that a bool flag has been set to true. This means if a function is called too many times it will fail the test.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e66b038de8b30d84403a73ed8d54bf69/href">https://medium.com/media/e66b038de8b30d84403a73ed8d54bf69/href</a></iframe><p>If we run these tests again with the introduced bug we get the following failure:</p><figure><img alt="Test failure message showing XCTAssertEqual failed: (“2”) is not equal to (“1”)" src="https://cdn-images-1.medium.com/max/806/1*6aUFHpljJo9Q-2fuo7LA3w.png" /></figure><p>Even though our test coverage is still 100%, we’ve now improved the <em>quality</em> of our unit tests by updating our mock view to check how many times our functions are called.</p><p>However, we can still take this one step further. Let’s look at another example:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5025e6b1807531f42862241008d5a280/href">https://medium.com/media/5025e6b1807531f42862241008d5a280/href</a></iframe><p>Can you spot the bugs in the above code? We’ve accidentally called hideLoading() and showLoading() the wrong way round. Now our loading spinner doesn’t show during loading, and instead shows when the message shows — oops!</p><figure><img alt="Tapping fetch message shows no loading spinner and then “Hello, world!” and loading spinner together" src="https://cdn-images-1.medium.com/max/552/1*E5cI80Kqy1eFw6UbBwnXbg.gif" /></figure><p>Even though we’ve introduced these bugs into our code, our updated unit tests will still pass because both hideLoading() and showLoading() are still being called the correct number of times (1) but they’re being called in the wrong order. Finally, let’s look at how we can update our mock and unit tests to also check the order in which the functions are called.</p><h3>Testing using an Array of captured events</h3><p>If you’re writing unit tests then you’re probably familiar with one of Swift’s primary collection types — array. An array is an ordered collection of values, so it seems like the perfect tool for the job of storing the order in which our mock’s functions are called.</p><p>Let’s update our mock by creating an enum where each case maps to an ‘event’ that our mock view should receive, such as showing the loading indicator. Then each time one of our mock view functions is called, we can ‘capture’ this event by adding the relevant case to an array of captured events.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c77c4ef8c8ea1069e8c53b3a895f10a1/href">https://medium.com/media/c77c4ef8c8ea1069e8c53b3a895f10a1/href</a></iframe><p>Now in our tests, we can assert that the array of captured events is equal to the array of events that we expect.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/11dcc15c605b8a9f3c96f0abb0bfdedc/href">https://medium.com/media/11dcc15c605b8a9f3c96f0abb0bfdedc/href</a></iframe><p>If we run the tests now with showLoading() and hideLoading() the wrong way round, the tests fail — woo! This means our unit tests are now not only testing <em>if</em> each function was called, but also <em>how many times</em> it was called, and <em>the order</em> in which they are called together.</p><p>One other benefit (in my opinion anyway) is that using a combination of array and enum in our mock makes our test code <em>much</em> more readable than the previous examples.</p><h4>Improving the failure message</h4><p>However, one thing you may notice with the above example is that our failure messages have become quite hard to read.</p><figure><img alt="Long and unreadable test failure message for captured events array mock" src="https://cdn-images-1.medium.com/max/674/1*RcWVLLUHdzVmI9eHFJ0D-w.png" /></figure><p>We can improve this is by adding raw value type of String to our Event enum. Then, we can make the Event enum conform to the CustomStringConvertible protocol which means we can provide a custom description for each case of Event by using the rawValue property.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f1cc88012dc1d5699a75322f158e2018/href">https://medium.com/media/f1cc88012dc1d5699a75322f158e2018/href</a></iframe><p>Now when our tests fail, we get nice readable failure messages that look the same as the array of expected events in your tests:</p><figure><img alt="Nice readable test failure message" src="https://cdn-images-1.medium.com/max/745/1*ZEb7v2cEb-lMxmNZuCMXBw.png" /></figure><h3>Wrapping up</h3><p>That’s it! We’ve covered a few different ways in which we can write mocks for our unit tests, and learned how we can improve our test quality by using an array of captured events.</p><p>If you have any comments or questions, or just want to say hi – feel free to <a href="https://twitter.com/GilroyBen">follow me on Twitter @GilroyBen</a> 👋</p><p>Thanks for reading! 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8c343c80d21" width="1" height="1" alt=""><hr><p><a href="https://medium.com/kinandcartacreated/using-array-to-improve-your-mocks-in-unit-tests-ios-swift-f8c343c80d21">Using Array to Improve your Mocks in Unit Tests (iOS &amp; Swift)</a> was originally published in <a href="https://medium.com/kinandcartacreated">Kin + Carta Created</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>