David S
David S

Reputation: 13871

Init params with patch and Mock with urllib2

I'm using Python 2.6.5 with Mock 0.7.2 and have a unit test where I use the patch decorator for a class.

@patch('urllib2.Request')
def test_do_my_call(self, MockClass):

    """will test that _do_my_call is getting called with correct values"""

    instance = MockClass.return_value
    mock_urlopen = Mock()
    mock_urlopen.return_value = 'foo'
    urllib2.urlopen = mock_urlopen

    response = do_something('MyData')

    self.assertEqual(mock_urlopen.call_count, 1)
    self.assertEqual(response, 'foo')

The above code passes, and it verifies that urlopen at least gets called, but it still seems a bit weak.

The "do_something" method creates a new request (hence the need for the patch) and then calls urlopen with it (and as noted above I verify that it gets called). But, I was wondering if there was a way to test parameters that got passed to urllib2.Request() from within "do_something". For example, did do_something pass the correct/expected url and the correct/expected headers?

Is this possible?

Upvotes: 2

Views: 778

Answers (2)

grncdr
grncdr

Reputation: 956

Because creating a Request instance does not have side-effects you shouldn't be mocking urllib2.Request, but instead inspecting the real Request instance that gets passed to your mocked urlopen to verify that it has the correct state.

Upvotes: 3

Eric Fortin
Eric Fortin

Reputation: 7603

Although I agree with grncdr, if your class had side effect, here's how you could do it:

from mock import Mock, patch

class MyClass(object):
    def __init__(self, a, b, c):
        pass

def method_to_test():
    m = MyClass(1, 'test', {'key' : 'value'})

@patch('__main__.MyClass')
def test_my_method(mock_class):
    method_to_test()
    mock_class.assert_called_with(1, 'test', {'key': 'value'})

test_my_method()

Upvotes: 1

Related Questions