skip to Main Content

I need to test saving the confirmation code to the Redis cache.

For example, there is a view that processes a user registration request. The view accepts a phone number and sends an SMS with a code to it. The code is generated by an additional function. Here’s how to mocking this function to send the code I need?

This is my view

def post(self, request):
    serializer = ReviewerSignUpSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)

    phone = serializer.validated_data.get("phone")
    confirmation_code = get_confirmation_code()
    cache.set(
        key=str(phone),
        value=confirmation_code,
        timeout=settings.CONFIRMATION_CODE_LIFETIME
    )

    send_sms_task.apply_async([confirmation_code, str(phone)])

This is a function that generates a confirmation code

def get_confirmation_code() -> str:
    seq = list(map(lambda x: str(x), range(10)))
    shuffle(seq)
    code = choices(seq, k=settings.INVITE_CODE_LENGTH)
    return "".join(code)

Test function

def test_saving_confirmation_code_in_cache(self, client, cache):
    phone = "+79389999999"
    generated_code = "9999"
    with patch("api.v1.authentication.utils.get_confirmation_code", return_value=generated_code):
        client.post(reverse('api:v1:signup'), data={'phone': phone})

    confirmation_code = cache.get(str(phone))
    assert confirmation_code is not None
    assert confirmation_code == generated_code

Perhaps, I need to test the entire view function?

2

Answers


  1. Chosen as BEST ANSWER

    Thank you all! My mistake is that I did not specify that the get_confirmation_code function is imported from another module.

    To solve my problem, I had to move this feature to my APIView. After that, everything worked

    def _get_confirmation_code(self) -> str:
        seq = list(map(lambda x: str(x), range(10)))
        shuffle(seq)
        code = choices(seq, k=settings.INVITE_CODE_LENGTH)
        return "".join(code)
    
    def post(self, request):
        serializer = ReviewerSignUpSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
    
        phone = serializer.validated_data.get("phone")
        confirmation_code = self._get_confirmation_code()
        cache.set(
            key=str(phone),
            value=confirmation_code,
            timeout=settings.CONFIRMATION_CODE_LIFETIME
        )
    
        send_sms_task.apply_async([confirmation_code, str(phone)])
    
    def test_saving_confirmation_code_in_cache(self, client, cache):
        phone = "+79389999999"
        generated_code = "9999"
        with patch(
                "api.v1.authentication.views."
                "ReviewerSignUpView._get_confirmation_code",
                return_value=generated_code
        ):
            client.post(reverse('api:v1:signup'), data={'phone': phone})
    
        confirmation_code = cache.get(str(phone))
        assert confirmation_code is not None
        assert confirmation_code == generated_code
    

  2. You have to patch the function in your views.py

    I assume the APIView class in your codebase is inside api.v1.authentication.views

    with patch("api.v1.authentication.views.get_confirmation_code", return_value=generated_code):
            client.post(reverse('api:v1:signup'), data={'phone': phone})
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search