2

スタッフ ユーザーが下書き状態のオブジェクトを表示できるビューが必要です。しかし、このビューの単体テストを書くのは難しいと思います。

セットアップにFactory Boyを使用しています:

class UserFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = User

    username = factory.LazyAttribute(lambda t: random_string())
    password = factory.PostGenerationMethodCall('set_password', 'mysecret')
    email = fuzzy.FuzzyText(
        length=12, suffix='@email.com').fuzz().lower()
    is_staff = True
    is_active = True

class ReleaseFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Release

    headline = factory.LazyAttribute(lambda t: random_string())
    slug = factory.LazyAttribute(lambda t: slugify(t.headline))
    author = factory.LazyAttribute(lambda t: random_string())
    excerpt = factory.LazyAttribute(lambda t: random_string())
    body = factory.LazyAttribute(lambda t: random_string())

class TestReleaseViews(TestCase):
    """
    Ensure our view returns a list of :model:`news.Release` objects.
    """

    def setUp(self):
        self.client = Client()
        self.user = UserFactory.create()
        self.client.login(username=self.user.username, password=self.user.password)

テスト用にログインしたスタッフ ユーザーがいる場合、それを使用してビュー (404 ではなく status_code 200) をテストするにはどうすればよいですか?

たとえば、このテストは失敗します (404 != 200) 私のビューでis_staffTrue を持つユーザーがビューにアクセスできる場合:

def test_staff_can_view_draft_releases(self):
    "ReleaseDetail view should return correct status code"
    release = ReleaseFactory.create(status='draft')
    response = self.client.get(
        reverse(
            'news:release_detail',
            kwargs={
                'year': release.created.strftime('%Y'),
                'month': release.created.strftime('%b').lower(),
                'day': release.created.strftime('%d'),
                'slug': release.slug
            }
        )
    )
    self.assertEqual(response.status_code, 200)
4

2 に答える 2

8

実際には、呼び出しが失敗404するため、エラーが発生します。self.client.login

を渡すときpassword=self.user.passwordは、パスワード自体ではなく、パスワードのハッシュを送信しています。

を呼び出すとUserFactory()、ファクトリで factory_boy が実行する手順は次のとおりです。

  1. でオブジェクトを作成する{'username': "<random>", 'is_active': True, 'is_staff': True, 'email': "<fuzzed>@email.com"}
  2. save()それ
  3. 電話user.set_password('my_secret')
  4. user.save()もう一度電話する

それまでにuser.passwordは の結果でありset_password('my_secret')、 ではありません'my_secret'

私は(あなたのテストで)行きます:

pwd = 'my_super_secret'
self.user = UserFactory(password=pwd)
self.client = Client()
self.assertTrue(self.client.login(username=self.user.username, password=pwd))

ところで、email フィールドの宣言は期待どおりに動作しません: を記述すると、これはクラスが宣言されたときに1 回だけfactory.fuzzy.FuzzyText(...).fuzz().lower()実行されます。UserFactory

代わりに を使用する必要がありますfactory.fuzzy.FuzzyText(chars='abcdefghijklmnopqrstuvwxyz', length=12, suffix='@example.com')

于 2015-04-19T14:56:16.550 に答える
0

クライアントを使用する代わりの方法として、ビューをインスタンス化してリクエストに直接渡すと便利であることがわかりました。

self.request.user = UserFactory()
view = ReleaseView.as_view()
response = view(self.request)

そして、あなたはすることができます

self.assertEqual(response.status_code, desired_status_code)

また、必要に応じて応答をレンダリングすることもできます。

于 2015-04-18T17:49:51.697 に答える