Установка свойства в запрос в тестовом клиенте Django

#django #django-tests

#django #django-тесты

Вопрос:

У меня есть промежуточное программное обеспечение (tenant_schemas.BaseTenantMiddleware), который будет вводить tenant свойство в объект запроса. Я не могу использовать это промежуточное программное обеспечение при модульном тестировании.

Затем в представлении я могу получить объект клиента из запроса. Это представление сопоставляется с URL-адресом «myapp: member_info».

 class MemberView(TemplateView):
    template_name = 'myapp/member.html'
    
    def get_context_data(self, member_id=None, *args, **kwargs):
        ctx = super().get_context_data(*args, **kwargs)
        tenant = self.request.tenant
        ctx['tenant_name'] = tenant.name
        return ctx
  

Это представление работает, когда проект выполняется нормально, поскольку промежуточное программное обеспечение будет установлено request.tenant правильно.

Теперь, если я хочу протестировать это представление, я пытаюсь написать следующий тест:

 class MemberViewTest(TestCase):
    def setUp(self):
        self.tenant = Tenant(name="test tenant")
        self.member = Member.objects.create(
            first_name='Test',
            last_name='Person')
        
    def test_saldo(self):
        self.client = Client(tenant=self.tenant) # Here I try to inject the tenant into the request
        print(self.client.defaults) # This will print {'tenant': <Tenant: test tenant>}
        response = self.client.get(reverse('myapp:member_info', kwargs={ 'tenant': self.tenant, 'member_id': self.member.token }))
  

Этот тест завершается ошибкой:

 File "myapp/views.py", line xxx, in get_context_data
    tenant = self.request.tenant
AttributeError: 'WSGIRequest' object has no attribute 'tenant'
  

Итак, django.tests.Класс Client не вводит значения по умолчанию в запрос.

Одна вещь, которую я пытался переопределить RequestFactory (https://github.com/django/django/blob/ac6c4260074de43a978e5c6553ef89441e1d6748/django/test/client.py#L308 ) так, чтобы он вводил арендатора.

 class TenantRequestFactory(RequestFactory):
    def request(self, **request):
        req = super().request(**request)
        req.tenant = Tenant()
        print(req)
        return req
        
class TenantClient(Client, TenantRequestFactory):
    pass

views.py
    def test_saldo(self):
        self.client = TenantClient(tenant=self.tenant)
  

Но TenantRequestFactory.request() никогда не вызывается (команда печати не выполняется). Я не знаю, должен ли я подклассировать его каким-либо другим способом? В client.py клиенте класс создается следующим образом: class Client(ClientMixin, RequestFactory)

Комментарии:

1. Почему вы вообще прикрепили атрибут к запросу? потому что я не вижу никакого использования request.tenant нигде

2. В представлении есть tenant = request.tenant и ctx['tenant_name'] = tenant.name то, что использует клиент. Я опустил шаблон, который будет использовать tenant_name , поскольку он не имеет отношения к делу.