87

私のdjangoアプリケーションでは、アクションを実行し、応答のメッセージをチェックする単体テストを作成しようとしています。

私の知る限り、これを行う良い方法はありません。

CookieStorageストレージメソッドを使用していますが、次のようなことをしたいと思います。

    response = self.client.post('/do-something/', follow=True)
    self.assertEquals(response.context['messages'][0], "fail.")

問題は、私が返すのは

print response.context['messages']
<django.contrib.messages.storage.cookie.CookieStorage object at 0x3c55250>

どうすればこれを何か便利なものに変えることができますか、それとも私はそれをすべて間違っていますか?

ありがとう、ダニエル

4

6 に答える 6

112

私は本当に簡単なアプローチを見つけました:

response = self.client.post('/foo/')
messages = list(response.context['messages'])
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), 'my message')

コンテキストのない応答のメッセージをチェックする必要がある場合は、以下を使用できます。

from django.contrib.messages import get_messages
messages = list(get_messages(response.wsgi_request))
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), 'my message')

フォールバックストレージはインデックス作成をサポートしていませんが、反復可能です。

于 2013-02-16T11:26:03.040 に答える
24

djangoのドキュメントから:

テンプレートの外では、get_messages()を使用できます

したがって、次のように書くことができます。

from django.contrib.messages import get_messages

[...]

messages = [m.message for m in get_messages(response.wsgi_request)]
self.assertIn('My message', messages)

于 2017-10-21T16:38:50.413 に答える
17

これは私にとってはうまくいきます(すべてのメッセージを表示します):

print [m.message for m in list(response.context['messages'])]

また、DjangoのTestCaseから継承されたテストクラスにあるユーティリティメソッドもいくつかあります。それらを関数として使用したい場合は、引数を削除し、'sを。selfに置き換えてください。self.fail()raise

def assert_message_count(self, response, expect_num):
    """
    Asserts that exactly the given number of messages have been sent.
    """

    actual_num = len(response.context['messages'])
    if actual_num != expect_num:
        self.fail('Message count was %d, expected %d' %
            (actual_num, expect_num))

def assert_message_contains(self, response, text, level=None):
    """
    Asserts that there is exactly one message containing the given text.
    """

    messages = response.context['messages']

    matches = [m for m in messages if text in m.message]

    if len(matches) == 1:
        msg = matches[0]
        if level is not None and msg.level != level:
            self.fail('There was one matching message but with different'
                'level: %s != %s' % (msg.level, level))

        return

    elif len(matches) == 0:
        messages_str = ", ".join('"%s"' % m for m in messages)
        self.fail('No message contained text "%s", messages were: %s' %
            (text, messages_str))
    else:
        self.fail('Multiple messages contained text "%s": %s' %
            (text, ", ".join(('"%s"' % m) for m in matches)))

def assert_message_not_contains(self, response, text):
    """ Assert that no message contains the given text. """

    messages = response.context['messages']

    matches = [m for m in messages if text in m.message]

    if len(matches) > 0:
        self.fail('Message(s) contained text "%s": %s' %
            (text, ", ".join(('"%s"' % m) for m in matches)))
于 2011-02-08T14:35:57.533 に答える
3

アップデート

私の元の答えは、djangoがまだ1.1かそこらだったときに書かれました。この答えはもはや関係ありません。より良い解決策については、@daveoncodeの回答を参照してください。

元の回答

私はこれをテストするために実験をしました。MESSAGE_STORAGEプロジェクトの1つで設定をに変更し、'django.contrib.messages.storage.cookie.CookieStorage'メッセージをチェックするために作成したテストを実行しました。機能した。

あなたがしていたこととの主な違いは、私がメッセージを取得する方法です。下記参照:

def test_message_sending(self):
    data = dict(...)
    response = self.client.post(reverse('my_view'), data)
    messages = self.user.get_and_delete_messages()

    self.assertTrue(messages)
    self.assertEqual('Hey there!', messages[0])

これは試してみる価値があるかもしれません。

于 2010-08-13T10:59:49.847 に答える
0

膠着状態のもののより単純なバージョン:

class TestCaseMessagesMixture(object):
    def assertMessageCount(self, response, expect_num):
        """
        Asserts that exactly the given number of messages have been sent.
        """

        actual_num = len(response.context['messages'])
        if actual_num != expect_num:
            self.fail('Message count was %d, expected %d' %
                    (actual_num, expect_num)
                )

    def assertMessageEqual(self, response, text):
        """
        Asserts that the response includes the message text.
        """

        messages = [m.message for m in response.context['messages']]

        if text not in messages:
            self.fail(
                'No message with text "%s", messages were: %s' % 
                    (text, messages)
                )

    def assertMessageNotEqual(self, response, text):
        """
        Asserts that the response does not include the message text.
        """

        messages = [m.message for m in response.context['messages']]

        if text in messages:
            self.fail(
                'Message with text "%s" found, messages were: %s' % 
                    (text, messages)
                )
于 2012-05-11T10:28:37.617 に答える
0

応答メッセージの数と内容を検証するためのテストヘルパー

def get_response_messages(self, response):
    from django.contrib.messages import get_messages
    return list(get_messages(response.wsgi_request))


def check_response_messages(self, response, message_index=None, message_value=None, exp_count=None):
    messages = self.get_response_messages(response)
    if exp_count is not None:
        self.assertEqual(len(messages), exp_count)

    if message_index is not None:
        message = messages[message_index]
        self.assertIn(message_value, str(message))

このように使用できます

message_value = "You can not switch to another type of account"
self.check_response_messages(response, exp_count=1, message_index=0, message_value=message_value)
于 2020-07-06T18:44:20.103 に答える