【问题标题】:Django 2.0 TestCase unexpected creation of Model objects for every testDjango 2.0 TestCase 为每个测试意外创建模型对象
【发布时间】:2018-03-14 16:23:33
【问题描述】:

我有一些测试,我需要一个使用 Board.objects.create() 创建的 Board 对象来拥有一个具有主键 1 的对象。但我发现,每个测试都有一个新对象,所以我有例如'pk': 5。如果我添加更多测试,'pk': 5 可能是错误的,因为它会更改为'pk': 6。怎么可能只为所有测试创建一个带有'pk': 1 的 Board 对象?

我正在使用 Django 2.0.3

from django.test import TestCase
from django.urls import reverse, resolve
from .views import home, board_topics, new_topic
from .models import Board

class BoardTopicsTests(TestCase):
    def setUp(self):
        Board.objects.create(name='Django', description='Django board.')

    def test_board_topics_view_success_status_code(self):
        url = reverse('boards:board_topics', kwargs={'pk': 5})
        response = self.client.get(url)
        self.assertEquals(response.status_code, 200)

    def test_board_topics_view_not_found_status_code(self):
        url = reverse('boards:board_topics', kwargs={'pk': 99})
        response = self.client.get(url)
        self.assertEquals(response.status_code, 404)

    def test_board_topics_url_resolves_board_topics_view(self):
        view = resolve('/boards/1/')
        self.assertEquals(view.func, board_topics)

    def test_board_topics_view_link_back_to_homepage(self):
        board_topics_url = reverse('boards:board_topics', kwargs={'pk': 3})
        response = self.client.get(board_topics_url)
        homepage_url = reverse('boards:home')
        self.assertContains(response, 'href="{0}"'.format(homepage_url))

    def test_board_topics_view_contains_navigation_links(self):
        board_topics_url = reverse('boards:board_topics', kwargs={'pk': 2})
        homepage_url = reverse('boards:home')
        new_topic_url = reverse('boards:new_topic', kwargs={'pk': 2})

        response = self.client.get(board_topics_url)

        self.assertContains(response, 'href="{0}"'.format(homepage_url))
        self.assertContains(response, 'href="{0}"'.format(new_topic_url))

【问题讨论】:

    标签: django django-testing django-tests


    【解决方案1】:

    您不应依赖已创建对象的主键。在这种情况下,您可以将板存储为属性,

    def setUp(self):
        self.board = Board.objects.create(name='Django', description='Django board.')
    

    然后在测试中使用它的pk。

    def test_board_topics_view_success_status_code(self):
        url = reverse('boards:board_topics', kwargs={'pk': self.board.pk})
    

    这将使您的测试套件更加健壮。目前,如果您运行测试的子集或以不同的顺序运行它们,您的测试可能会失败。

    【讨论】:

    • 我也遇到过类似的情况,测试用例只创建了一个实例,但是pk=1 不匹配查询。为什么会这样?
    • 谢谢。感觉像是一种解决方法,但这有助于解决这个“问题”以获得更强大的测试。
    • 如果你真的想要你可以在setUp 方法中强制使用Board.objects.create(pk=1, name='Django', description='Django board.') 的主键,但你不应该这样做。最好避免在测试中对 pk 进行硬编码,因此我不会将我的代码描述为解决方法。想象一下,如果您正在测试一个创建对象的视图。现在您不能强制使用主键,除非您修改代码或更改数据库序列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 2021-10-30
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 2023-01-02
    相关资源
    最近更新 更多