You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django测试中mock未被调用:如何正确模拟validate_sns_token函数?

Fixing the Mock Issue for validate_sns_token in Your Django Test

It looks like your mock isn't replacing the original function because of how Python's mocking system targets references. Let's break down the problem and fix it step by step.

Why Your Current Mock Isn't Working

Even though you're targeting user.serializers.validate_sns_token, there are a few edge cases where this might not replace the function that's actually being called in your serializer's create method:

  • String-based paths can be error-prone if your project structure has nested modules, or if imports are cached in a way that bypasses the patch.
  • If your create method references the function directly (as a local name in the serializers.py file), you need to ensure the patch targets the exact reference being used.

Solution 1: Use patch.object for Reliable Mocking

Instead of using a string path, use patch.object to directly target the function on the imported serializers module. This avoids path-related mistakes and ensures you're overriding the exact reference your create method uses.

Here's the updated test code:

from django.test import TestCase
from unittest.mock import patch
from user import serializers  # Import the module directly
from rest_framework import status

class UserCreationTest(TestCase):
    # ... your setup and other test methods ...

    @patch.object(serializers, 'validate_sns_token', return_value=True)
    def test_can_create_user(self, validate_mock):
        """Test that user can be created without logging in"""
        user_payload = self.generate_user_payload()
        resp = self.client.post(
            CREATE_USER_URL,
            user_payload,
        )

        # Verify the mock was called
        self.assertTrue(validate_mock.called)
        # Verify the response is successful
        self.assertEqual(
            resp.status_code,
            status.HTTP_200_OK,
        )

Solution 2: Verify Your Patch Path (If You Prefer String-Based Patching)

If you want to stick with the string path approach, confirm the exact module path of the function being called:

  1. Add this line to your test file to check the function's module:
    from user.serializers import validate_sns_token
    print(validate_sns_token.__module__)  # Should output "user.serializers"
    
  2. If the output is different (e.g., user.api.serializers), update your patch path to match that exact string.

Additional Checks to Rule Out Other Issues

  • Ensure your payload has required fields: Double-check that generate_user_payload() includes sns_id, sns_type, and token—if these are missing, your create method might skip calling validate_sns_token entirely.
  • Debug mock calls: Add print(validate_mock.mock_calls) to your test to see exactly when (or if) the mock is being invoked, and what arguments are passed to it. This will help confirm if the mock is being hit at all.

By using patch.object, you're directly modifying the function reference in the serializers module that your create method uses—this guarantees the original function won't run, and your mock's return value will be used instead.

内容的提问来源于stack exchange,提问作者forJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:12:32