Houman
Houman

Reputation: 66380

How to make a distinction between static methods and instance methods when mocking a class?

I came across a bug in production, even though it should have been tested by the unit tests.

class Stage2TaskView(MethodView):
    def post(self):
        json_data = json.loads(request.data)
        news_url_string = json_data['news_url_string']
        OpenCalais().generate_tags_for_news(news_url_string) // ?
        return "", 201

This used to be a static:

OpenCalais.generate_tags_for_news(news_url_string)

But then I changed the method and removed the static decorator. But I forgot to change that line to

OpenCalais().generate_tags_for_news(news_url_string)

The test doesn't see it though. How can I test this in future?

@mock.patch('news.opencalais.opencalais.OpenCalais.generate_tags_for_news')
def test_url_stage2_points_to_correct_class(self, mo):
    rv = self.client.post('/worker/stage-2', data=json.dumps({'news_url_string': 'x'}))
    self.assertEqual(rv.status_code, 201)

Upvotes: 1

Views: 40

Answers (1)

Michele d'Amico
Michele d'Amico

Reputation: 23741

Autospeccing is your fried! Use autospec=True in patch decorator will check the complete signature:

class A():
    def no_static_method(self):
        pass

with patch(__name__+'.A.no_static_method', autospec=True):
    A.no_static_method()

will raise an exception:

Traceback (most recent call last):
  File "/home/damico/PycharmProjects/mock_import/autospec.py", line 9, in <module>
    A.no_static_method()
TypeError: unbound method no_static_method() must be called with A instance as first argument (got nothing instead)

Upvotes: 2

Related Questions