【问题标题】:How to test if view is able to create a new entity in the db?如何测试视图是否能够在数据库中创建新实体?
【发布时间】:2020-04-02 09:09:04
【问题描述】:

为了提高我的代码覆盖率,我必须进行基本的单元测试。我不需要做任何花哨的事情。只需要最低限度。所以,在这种情况下,如果我能够成功地击中我的视图,那么这就是我需要做的。 如您在 models.py 中所见,敏捷团队嵌套在 Team 下。

models.py -

class Organization(models.Model):
    orgname = models.CharField(max_length = 100, blank=True)

    def __str__(self):
        return str(self.orgname)

class Team(models.Model):
    teamID = models.AutoField(primary_key=True)
    teamName = models.CharField(max_length = 100, blank=True)
    org = models.ForeignKey(Organization, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.teamName)

class AgileTeam(models.Model):
    agileTeamID = models.AutoField(primary_key=True)
    agileTeamName = models.CharField(max_length = 100, blank=True)
    team = models.ForeignKey(Team,  on_delete=models.CASCADE)

    def __str__(self):
        return str(self.agileTeamName)

views.py -

@csrf_exempt
def newATeam(request):
    if request.method == 'POST':
        param = json.loads(request.body)
        agileteam = param.get('agileteam')
        teamname = param.get('teamname')
        team = Team.objects.get(teamName = teamname)
        AgileTeam.objects.create(agileTeamName=agileteam, team=team)
        return JsonResponse(status = 200, data = {})

urls.py -

path('ajax/newATeam/', views_admin.newATeam, name='ajax_newATeam'),

test_views.py -

class TestViews(TestCase):
@classmethod
    def setUpTestData(self):
        # set-up org
        ORG_NAMES = ['REVCYCSCH', 'DIABLO', 'BROTHERHOOD']
        for org in ORG_NAMES:
            Organization.objects.create(orgname=org)

        # set-up team
        orgModels = Organization.objects.all()
        TEAM_NAMES = ['Blitzkrieg ', 'Hammerheads', 'Mercenaries']
        for i in range(len(TEAM_NAMES)):
            Team.objects.create(teamName=TEAM_NAMES[i], org=orgModels[i])

        # set-up agileteam
        teamModels = Team.objects.all()
        AGILE_TEAM_NAMES = ['Barons', 'Exterminators ', 'Mavericks', 'Renegades', 'Stratosphere', 'Trojans ']
        index = 0
        for team in teamModels:
            for _ in range(2):
                AgileTeam.objects.create(agileTeamName=AGILE_TEAM_NAMES[index], team=team)
                index = index + 1

        self.client = Client()

        def test_newATeam(self):
            params = {'agileteam': 'Barons', 'teamname': 'Blitzkrieg'}
            response = self.client.post(path = '/ajax/newATeam/', data = params, content_type = 'application/json')
            self.assertEqual(response.status_code, 200) 

但是,我收到此错误 - Error

提前致谢!

【问题讨论】:

    标签: python django unit-testing


    【解决方案1】:

    我会做一些稍微不同的事情。

    views.py:

    @csrf_exempt
    def new_agile_team(request):
        if request.method == 'POST':
            if request.META.get('CONTENT_TYPE', '').lower() == 'application/json' and len(request.body) > 0:
                try:
                    body_data = json.loads(request.body.decode('utf-8'))
                except Exception as e:
                    return HttpResponseBadRequest(json.dumps({
                        'error': 'Invalid request: {0}'.format(str(e))
                     }), content_type="application/json")
    
            try:
                team = Team.objects.get(teamName = teamname)
                AgileTeam.objects.create(agileTeamName=agileteam, team=team)
            except Team.DoesNotExist as error:
                # Handle error here...
    
            return JsonResponse(status = 200, data = {})
    

    但是,我强烈建议为此使用 Djago REST 框架 - 因为您可能只需要为登录用户提供创建团队的能力,因此您需要了解路由的 @action 级别权限,以及利用更 RESTful 的原则。

    【讨论】:

    • 这是一个基础级别的项目。我不需要登录用户。我需要做的就是在我的测试用例中看到我的观点。
    【解决方案2】:

    所以...您正在发送'teamName': 'Blitzkrieg',但随后您正在获取teamname = param.get('teamname')...当然它不起作用,您是否尝试过调试它?

    我看到这段代码有很多问题,我只是不知道从哪里开始,但只是开始使用PEP8 + Djagno Coding styles(可能还有一些 linter 和格式化程序),你的生活会变得容易多了。

    【讨论】:

    • 毫无疑问,我确实有很多东西要学。你能告诉我在我的测试代码中要改变什么吗?
    • 您应该发送params = {'agileteam': 'Barons', 'teamname': 'Blitzkrieg'},因为这是您的视图所期望的关键字参数。或者您应该更新您的视图以获取 agileteam = param.get('agileTeamName'); teamname = param.get('teamName'),因为这是您的测试发送的内容。
    • 为了澄清,我的观点是从 AJAX 调用中获取数据。我已使用您在上面发送的代码更新了原始帖子中的 test_view,但仍然出现相同的错误。
    • 'Blitzkrieg ' 中有一个额外的空格
    猜你喜欢
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 2018-12-07
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多