<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Testing on The Edge Cases</title>
    <link>https://www.kylestratis.com/tags/testing/</link>
    <description>Recent content in Testing on The Edge Cases</description>
    <generator>Hugo</generator>
    <language>en</language>
    <copyright>© 2025</copyright>
    <lastBuildDate>Fri, 18 Sep 2026 22:38:55 -0400</lastBuildDate>
    <atom:link href="https://www.kylestratis.com/tags/testing/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Strategies for Mocking AWS Services for Testing</title>
      <link>https://www.kylestratis.com/notes/strategies-for-mocking-aws-services-for-testing/</link>
      <pubDate>Sat, 19 Sep 2026 02:10:03 +0000</pubDate>
      <guid>https://www.kylestratis.com/notes/strategies-for-mocking-aws-services-for-testing/</guid>
      <description>&lt;h2 id=&#34;stubber&#34;&gt;Stubber&lt;/h2&gt;&#xA;&lt;p&gt;Boto3 comes with the &lt;code&gt;Stubber&lt;/code&gt; class, but it doesn&amp;rsquo;t work well for all calls. In those cases&lt;/p&gt;&#xA;&lt;h2 id=&#34;moto&#34;&gt;Moto&lt;/h2&gt;&#xA;&lt;p&gt;Moto is a Python package that allows for easy mocking of AWS services. The canonical way to do this is to use the &lt;code&gt;@mock_&amp;lt;service&amp;gt;&lt;/code&gt; decorator outside of your test function and call &lt;code&gt;boto3&lt;/code&gt; functions there. Moto will detect and intercept the &lt;code&gt;boto3&lt;/code&gt; calls. Code example from the Moto documentation:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; boto3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; moto &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; mock_s3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; mymodule &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; MyModel&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@mock_s3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_my_model_save&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; conn &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; boto3&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;resource(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s3&amp;#39;&lt;/span&gt;, region_name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;us-east-1&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# We need to create the bucket since this is all in Moto&amp;#39;s &amp;#39;virtual&amp;#39; AWS account&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; conn&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;create_bucket(Bucket&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mybucket&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; model_instance &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MyModel(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;steve&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;is awesome&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; model_instance&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;save&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; body &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; conn&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Object(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mybucket&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;steve&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get[&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Body&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;read&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;decode(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; body &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;is awesome&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;patching-clients-and-resources&#34;&gt;Patching Clients and Resources&lt;/h3&gt;&#xA;&lt;p&gt;This is kind of useless for most testing, where there is an external module or package under test. The Moto documentation advises users to set up their &lt;code&gt;boto3&lt;/code&gt; clients and/or resources within the functions that use them, but this isn&amp;rsquo;t always workable. Instead, since you&amp;rsquo;re already importing the module or package under test, you can use Moto&amp;rsquo;s &lt;code&gt;patch_client&lt;/code&gt; or &lt;code&gt;patch_resource&lt;/code&gt; to patch the instantiated client or resource:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Testing Python Code with Pytest</title>
      <link>https://www.kylestratis.com/notes/testing-python-code-with-pytest/</link>
      <pubDate>Mon, 14 Mar 2022 19:20:53 +0000</pubDate>
      <guid>https://www.kylestratis.com/notes/testing-python-code-with-pytest/</guid>
      <description>&lt;h2 id=&#34;mocking-external-code&#34;&gt;Mocking External Code&lt;/h2&gt;&#xA;&lt;p&gt;To mock outside function calls with Pytest, install the &lt;code&gt;pytest-mock&lt;/code&gt; package and use &lt;code&gt;mocker&lt;/code&gt; as a parameter to your test function. Then you set the patch with the following syntax: &lt;code&gt;mocker.patch.object(Class, &amp;quot;function_name&amp;quot;, replacement_function)&lt;/code&gt;. Note how there aren&amp;rsquo;t any parantheses for the functions - either in the string representation or the actual function. This is because if they were used, the function would be evaluated at the call, rather than passed in to the patch.object function. These are best done in setup functions rather than the test function itself.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
