0

I want to cause Path.exists() to only return True when a specific Path is being tested:

    from unittest import TestCase
    from mock import patch
    import pathlib

    def fn(names):
      for index, name in enumerate(names):
        if pathlib.Path(name).exists():
          return index

    class T(TestCase):
      @patch.object(pathlib.Path, 'exists', side_effect=lambda: self.name == "countme")
      def test_fn(self, exists_mock):
        self.assertEqual(2, fn(["not", "not", "countme", "not"]))

I've also tried using

      @patch.object(pathlib.Path, 'exists', side_effect=lambda self: self.name == "countme")
kfsone
  • 23,617
  • 2
  • 42
  • 74

1 Answers1

1

Your code is almost correct. Here is a working version:

class T(TestCase):
   @patch.object(pathlib.Path, 'exists', lambda self: self.name == "countme")
    def test_fn(self):
        self.assertEqual(2, fn(["not", "not", "countme", "not"]))

Your use of the lambda missed the lambda parameter, and instead of using side_effect, you have to just replace the function.
The problem is that side_effect is just a return value (or a list of return values) that is independent of the real function call, so using the lambda will not work - it will not be called with self as parameter. The new parameter which is used instead, replaces the actual function, so it will be called with the correct argument.

A similar version using patch would look like this:

class T(TestCase):
    @patch('pathlib.Path.exists', lambda self: self.name == "countme")
    def test_fn(self):
        self.assertEqual(2, fn(["not", "not", "countme", "not"]))
MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46