2

私は RethinkDB のデータベース ラッパーを Python で作成しました。これは、モデルを導入するラッパーです (モデルとマネージャーに関して Django が提供するものと同様のもの)。ユニットテストを書くにはどうすればよいですか?実際、モデルに与えた値でデータベースが更新されているかどうかをテストするにはどうすればよいでしょうか?

実際にデータベースにクエリを実行することを考えましたが、これは実際に機能しますが、これは、テストを実行するたびにデータベースへの接続を作成する (およびデータベースをセットアップする) 必要があることを意味します。データベースまたは接続をモックする方法はありますか?

現在、テストのメソッドで接続オブジェクトを作成し、テストsetUp()用のデータベースを作成し、tearDown()メソッドで上記の操作を削除しています。

4

1 に答える 1

2

unittest.mockを使用して、ラッパーの実装に使用している低レベル API をモックし、アサートを使用してラッパーから API への呼び出しをチェックできます。

私は django モデルや rethinkdb についてあまり知りませんが、このように見えるかもしれません。

import uuid import unittest import unittest.mock as mock

import wrapper # your wrapper


class Person(wrapper.Model):
    name = wrapper.CharField()

class Tests(unittest.TestCase):
    def setUp(self):
        # you can mock the whole low-level API module
        self.mock_r = mock.Mock()
        self.r_patcher = mock.patch.dict('rethinkdb', rethinkdb=self.mock_r):
        self.r_patcher.start()
        wrapper.connect('localhost', 1234, 'db')

    def tearDown(self):
        self.r_patcher.stop()

    def test_create(self):
        """Test successful document creation."""
        id = uuid.uuid4()
        # rethinkdb.table('persons').insert(...) will return this
        self.mock_r.table().insert.return_value = {
            "deleted": 0,
            "errors": 0,
            "generated_keys": [
                id
            ],
            "inserted": 1,
            "replaced": 0,
            "skipped": 0,
            "unchanged": 0
        }

        name = 'Smith'
        person = wrapper.Person(name=name)
        person.save()

        # checking for a call like rethinkdb.table('persons').insert(...)
        self.mock_r.table.assert_called_once_with('persons')
        expected = {'name': name}
        self.mock_r.table().insert.assert_called_once_with(expected)

        # checking the generated id
        self.assertEqual(person.id, id)

    def test_create_error(self):
        """Test error during document creation."""
        error_msg = "boom!"
        self.mock_r.table().insert.return_value = {
            "deleted": 0,
            "errors": 1,
            "first_error": error_msg
            "inserted": 0,
            "replaced": 0,
            "skipped": 0,
            "unchanged": 0
        }

        name = 'Smith'
        person = wrapper.Person(name=name)

        # expecting error
        with self.assertRaises(wrapper.Error) as error:
            person.save()
        # checking the error message
        self.assertEqual(str(error), error_msg)

このコードはかなり大雑把ですが、理解していただければ幸いです。

編集:エラーを追加return_valueしてテストします。

于 2014-04-16T09:29:25.397 に答える