0

I am writing some code, in Python 3.4, that depends on a module that hasn't yet be written so would like to mock that import so I can still run tests on the code without running into an ImportError. Here is a sample bit of code I would like to test:

foo.py - simple class that checks params and then calls a method

from bar import Bar
from notcreated import NotCreated

class Foo:
    def method(self, bar, notCreated):
        # check time param is of correct type
        if not isinstance(bar, Bar):
            raise TypeError("bar of wrong type")

        # check notCreated param
        if not isinstance(notCreated, NotCreated):
            raise TypeError("notCreated of wrong type")

        notCreated.callMethod(bar)

bar.py

class Bar:
    def __init__(self, param):
        self.param = param

And a sample test class:

test_foo.py

from unittest import TestCase
from unittest.mock import patch, MagicMock
from bar import Bar

class TestFoo(TestCase):
    def setUp(self):
        self.notcreated = MagicMock()
        self.notcreated.NotCreated.callMethod.return_value = None

        modules = {'notcreated': self.notcreated}

        self.patch = patch.dict('sys.modules', modules)
        self.patch.start()

        from foo import Foo
        self.Foo = Foo

    def test_time(self):
        bar = MagicMock(Bar)
        notCreated = self.notcreated.NotCreated

        foo = self.Foo()
        foo.method(bar, notCreated)

        self.notcreated.NotCreated.callMethod.assert_called_with(bar)

    def tearDown(self):
        self.patch.stop()

However when I run the test I get the following error:

Error
Traceback (most recent call last):
  File "C:\Users\Oliver\PycharmProjects\PatchingImports\test_foo.py", line 27, in test_time
    foo.method(bar, notCreated)
  File "C:\Users\Oliver\PycharmProjects\PatchingImports\foo.py", line 14, in method
    if not isinstance(notCreated, NotCreated):
TypeError: isinstance() arg 2 must be a type or tuple of types

For some reason isinstance doesn't seem to thing that the Mocked NotCreated has a type although it is fine with the Mock created for Bar.

Any help would me much appreciated. :)

Ollie
  • 473
  • 3
  • 7
  • 19
  • Note that you should not be inserting `notcreated.NotCreated` into `sys.modules` here. It is not a module itself. – Martijn Pieters Jul 17 '15 at 12:50
  • The answer you marked as duplicate doesn't answer my question. I don't want to check to check the class's attributes I want to test it is of the same type. This is just an example but I'm doing more than just a method call on the `NotCreated` object. – Ollie Jul 17 '15 at 12:59
  • The answers there tell you why you cannot do that; mocking a class then using `isinstance()` is not supported. – Martijn Pieters Jul 17 '15 at 13:01
  • 1
    If duck-typing isn't going to work for you, then you'll need to supply your own test class. A `MagicMock` instance is not a class and cannot be used in an `isinstance()` test. – Martijn Pieters Jul 17 '15 at 13:03
  • So does it work for `Bar` because `from bar import Bar` is still a class where as `from notcreated import NotCreated` is an now an instance of a class and not a class itself? – Ollie Jul 17 '15 at 13:18
  • 1
    Exactly, `Bar` is an actual Python type (a custom class), while `NotCreated` is not. – Martijn Pieters Jul 17 '15 at 13:20
  • Argh okay thank you for clarifying that for me. :) – Ollie Jul 17 '15 at 13:21

0 Answers0