2

一時的な内部オブジェクトの特定のメソッドを呼び出すかどうかにかかわらず、メソッドをテストしたいと思います。(ConfigParser.read)

したがって、オブジェクトは内部で作成され、メソッドが終了した後は外部からアクセスできません。

Python 2.7 の使用

foob​​ar.py で

 import ConfigParser

 class FooBar:
     def method(self, filename):
         config=ConfigParser.ConfigParser()
         config.read(filename)
         do_some_stuff()

config.read が呼び出されたかどうかをテストしたいと思います。

私が理解しているように、パッチデコレータはこれのために作成されましたが、残念ながら、テストケースが受け取る MagicMock オブジェクトは内部で作成されたものと同じではなく、メソッド内に存在するオブジェクトに近づくことができません。

私はこのように試しました:

class TestFooBar(TestCase):

    def setUp(self):
         self.myfoobar = FooBar()

    @mock.patch('foobar.ConfigParser')
    def test_read(self,mock_foobar):
        self.myfoobar.method("configuration.ini")
        assert mock_foobar.called # THIS IS OKAY
        assert mock_foobar.read.called # THIS FAILS
        mock_foobar.read.assert_called_with("configuration.ini") # FAILS TOO

問題は次のとおりです。- デバッグ時、mock_foobar には以前の呼び出しに関する内部データがありますが、「読み取り」プロパティはありません (読み取りメソッドをモックするための内部 MagicMock)

もちろん、リファクタリングして .read() やinit () に ConfigReader オブジェクトを与えるのも一つの方法ですが、常にコードを変更できるとは限らず、モジュールに触れずにメソッドの内部オブジェクトを把握したいと考えています。テスト中。

4

1 に答える 1

4

あなたはとても近いです!問題は、クラスをモックしていることですが、テストではそのモック クラスで read() が呼び出されることを確認しますが、実際には、クラスを呼び出したときに返されるインスタンスで read() が呼び出されることを期待しています。次のように動作します - 2 番目のテストは最初のテストよりも読みやすいと思いますが、どちらも機能します。

import ConfigParser
from unittest import TestCase

from mock import create_autospec, patch, Mock 


class FooBar(object):
    def method(self, filename):
        config=ConfigParser.ConfigParser()
        config.read(filename)


class TestFooBar(TestCase):

    def setUp(self):
         self.myfoobar = FooBar()

    @patch('ConfigParser.ConfigParser')
    def test_method(self, config_parser_class_mock):
        config_parser_mock = config_parser_class_mock.return_value

        self.myfoobar.method("configuration.ini")

        config_parser_class_mock.assert_called_once_with()
        config_parser_mock.read.assert_called_once_with("configuration.ini")

    def test_method_better(self):
        config_parser_mock = create_autospec(ConfigParser.ConfigParser, instance=True)
        config_parser_class_mock = Mock(return_value=config_parser_mock)

        with patch('ConfigParser.ConfigParser', config_parser_class_mock):
            self.myfoobar.method("configuration.ini")

        config_parser_class_mock.assert_called_once_with()
        config_parser_mock.read.assert_called_once_with("configuration.ini")
于 2015-08-26T23:14:06.427 に答える