ちんぱんの雑記

チラシの裏

mock を使うとき、autospec を併用するといいかも!

autospec を使うことで、もともとのオブジェクトの挙動を模倣してくれます。

逆に、使わなければ模倣しないわけです。

 

なので、autospec を使わない場合、予期しない引数で呼ばれたり、

typo などによる存在しないメソッドの呼び出しがあったとき、エラーが発生しない可能性があるわけです。

 

例えば、次のようなクラスがあるとします。

class Calculator:
    def add(self, num1: int, num2: int) -> int:
        return num1 + num2

 

そして、テストはこんな感じ。

autospec を説明するためのコードであり、テストコードとしてはイケてないのは勘弁してほしい。

from my_test.my_test import Calculator
from unittest import mock


def test_add() -> None:
    with mock.patch.object(Calculator, "add", autospec=True):
        test_instance = Calculator()
        test_instance.add(1, 2)


def test_add2() -> None:
    with mock.patch.object(Calculator, "add"):
        test_instance = Calculator()
        test_instance.add(1, 2, 3)

 

test_add は呼び出し方に何ら問題はないので、当然成功してほしいです。

test_add2 では add に渡す引数が多く、使い方を誤っているので成功してほしくないわけです。

 

autospec を使っていないので Calculator クラスの本来の挙動を模倣してくれません。

なので、おかしなことをしていると検知できず、このテストは成功となってしまいます。

いけませんね。

 

なので、mock を使うときは autospec を積極的に使うべきだなあと思いました。

 

そもそも、静的解析を使っていると警告が出てくるので未然に防げるのですが…。