Pythonのunittestライブラリには、テスト対象のクラスメソッドをモック化する機能があります。これにより、テスト対象のメソッドが正しく呼び出されているかを確認したり、テスト対象のメソッドの挙動を制御したりすることが可能になります。
モックの基本
PythonのunittestライブラリにはMagicMockというクラスがあります。このクラスを使うと、任意のオブジェクトをモック化することができます。モック化されたオブジェクトは、元のオブジェクトと同じインターフェースを持ちつつ、その挙動を自由に制御することができます。
例えば、以下のようにして特定のメソッドをモック化することができます。
from unittest.mock import MagicMock
class SomeClass:
def method(self):
pass
real = SomeClass()
real.method = MagicMock(name='method')
このコードでは、SomeClassのインスタンスrealのmethodメソッドをMagicMockインスタンスで置き換えています。これにより、methodメソッドがどのように呼び出されたかを後から確認することができます。
メソッドの呼び出しを確認する
モック化されたメソッドが呼び出されたかどうかは、called属性を見ることで確認できます。また、assert_called_withメソッドを使うと、モック化されたメソッドが期待通りの引数で呼び出されたかを確認することができます。
以下に具体的な例を示します。
class ProductionClass:
def method(self):
self.something(1, 2, 3)
def something(self, a, b, c):
pass
real = ProductionClass()
real.something = MagicMock()
real.method()
real.something.assert_called_once_with(1, 2, 3)
このコードでは、ProductionClassのsomethingメソッドをモック化し、その後でmethodメソッドを呼び出しています。その結果、somethingメソッドが1, 2, 3という引数で一度だけ呼び出されたことを確認しています。
クラスをモック化する
unittestライブラリには、クラス全体をモック化する機能もあります。これにより、テスト対象のコードが新たにクラスのインスタンスを作成する場合でも、そのインスタンスをモック化することができます。
以下に具体的な例を示します。
from unittest.mock import patch
def some_function():
instance = module.Foo()
return instance.method()
with patch('module.Foo') as mock:
instance = mock.return_value
instance.method.return_value = 'the result'
result = some_function()
assert result == 'the result'
このコードでは、patch関数を使ってmodule.Fooクラスをモック化しています。その結果、some_function関数がmodule.Fooのインスタンスを作成しようとすると、代わりにモック化されたインスタンスが作成されます。
以上、Pythonのunittestライブラリを使ったクラスメソッドのモック化について説明しました。これにより、テスト対象のメソッドが正しく呼び出されているかを確認したり、テスト対象のメソッドの挙動を制御したりすることが可能になります。ユニットテストを書く際には、ぜひこの機能を活用してみてください。