title: Testing/Mocking a context management protocol - Pytest
body: <p>Currently trying to figure out the best practice when it comes to testing nested with-statements while avoiding unnecessary boilerplate code. Here is a snippet of the code which I would like to test the behavior of:</p>
  <pre><code>def my_func(input_file: Path, output_file: Path) -&gt; None:
      &quot;&quot;&quot;
      This function is used to extract a pattern and write it to an output file.
      &quot;&quot;&quot;
  
      # Pattern to extract
      regex_pattern = r&quot;some pattern&quot;
      # Check if the input file exists
      if not os.path.exists(input_file):
          raise Exception(f&quot;The input file: {os.path.abspath(input_file)} does not exist!&quot;)
  
      # Use the string representation of the path object:
      try:
          # Open the input file and output file for reading and writing
          with open(input_file, &quot;r&quot;) as input_file_handle:
              with open(output_file, &quot;w&quot;) as output_file_handle:
                  for line in input_file_handle:
                      if re.match(regex_pattern, line):
                          output_file_handle.write(line)
          print(&quot;Extraction complete!&quot;)
      
      # TODO: Exception scope too wide, (fix me)
      except Exception as e:
          print(e)
  </code></pre>
  <p>What would be the best approach to use for writing a test case?</p>
  <p>The easiest way I could think of is having a set of input data that gets parsed through the test function, using a pre-defined fixture for creating a <code>/tmp/</code> folder to store the context of the input data for writing to the input file then calling <code>my_func()</code> and reading the content of the output file and assert that the data matches the expected output.</p>
  <pre><code>import os
  from pathlib import Path
  import pytest
  import tempfile
  import shutil
  
  
  @pytest.fixture()
  def mk_temp_dir():
      &quot;&quot;&quot;
      Fixture for pytest
      &quot;&quot;&quot;
      # set up
      temp_dir = tempfile.mkdtemp()
  
      yield temp_dir
  
      # tear down
      shutil.rmtree(mk_temp_dir)
  
  def test_key_features(mk_temp_dir: str) -&gt; None:
      &quot;&quot;&quot;
      This function is used to set up the test environment.
      &quot;&quot;&quot;
      print(&quot;Setting up the test environment...&quot;)
      input_lines = [
          &quot;aaa&quot;,
          &quot;aa&quot;,
          &quot;bbb&quot;,
          &quot;bb&quot;,
          &quot;ccc&quot;,
      ]
      expected_lines = [&quot;aaa&quot;, &quot;bbb&quot;, &quot;ccc&quot;]
      # setup a tmp directory for testing
      mk_temp_dir = Path(temp_dir)
  
      # write a few lines for testing to the input file
      with open(mk_temp_dir / &quot;input.txt&quot;, mode=&quot;w&quot;) as input_file:
          print(os.listdir(mk_temp_dir))
          input_file.write(&quot;\n&quot;.join(input_lines))
  
      # DEBUG: read the content of the input file
      with open(mk_temp_dir / &quot;input.txt&quot;, mode=&quot;r&quot;) as input_file_handle:
          input_lines = input_file_handle.read().splitlines()
          print(input_lines)
  
      # pass it to the function
      key_features.extract_key_features(
          mk_temp_dir / &quot;input.txt&quot;,
          mk_temp_dir / &quot;output.txt&quot;,
      )
      print(&quot;Test environment setup complete!&quot;)
  
      with open(mk_temp_dir / &quot;output.txt&quot;, mode=&quot;r&quot;) as output_file:
          # read the ouput file and assert the expected data is there
          assert output_file.read().splitlines() == expected_lines
  </code></pre>
  <p>But it seems like there's might be an issue with the function itself since the test case seems to cover the functionality.</p>