doc.dev1x.org

Dependency Injection

1. 目的

処理をモック化して効率よくユニットテストを実施したい

2. 課題

プログラムの中で具体的な処理を記述するとモック化が困難である

# requests(HTTP通信ライブラリ)を使用する
import requests

class Program:
    def run(url):
        # 引数で指定されたURLにアクセスし、取得したデータを返却する
        res = requests.get(url)
        return res.text

if __name__ == '__main__':
    p = Program()
    result = p.run('http://example.com')
    print(result)

3. 解決策

モック化したい処理は別モジュールにして、プログラムの外から渡すようにする

import requests

class HttpRequest:
    def get(url):
        return requests.get(url)

class Program:
    def __init__(self, request):
        self.request = request

    def run(url):
        res = self.request.get(url)
        return res.text

if __name__ == '__main__':
    req = HttpRequest()
    p = Program(req)
    result = p.run('http://example.com')
    print(result)
import requests

class HttpRequest:
    def get(url):
        return requests.get(url)

class MockHttpRequest:
    def get(url):
        result = type('', (), {})
        result.text = 'Year!'
        return result

class Program:
    def __init__(self, request):
        self.request = request

    def run(url):
        res = self.request.get(url)
        return res.text

if __name__ == '__main__':
    # HTTP通信部分をモックに差し替え
    req = MockHttpRequest()
    p = Program(req)
    result = p.run('http://example.com')
    print(result) # Year!

4. メリット

任意の処理をモック化しやすくなる

5. デメリット

プログラムの複雑性が上がる

6. 注意事項

やりすぎない

参考資料

関連