使用graphene-django编写GraphQL测试用例时execute方法调用异常
问题
使用graphene-django编写测试用例验证GraphQL API时,执行查询报错AttributeError: 'Client' object has no attribute 'execute',但dir()输出明明显示Client对象存在execute方法。
测试代码
from django.test import TestCase from graphene.test import Client from app.graphql.schema import schema from app.graphql.tests import constants def generate_token(user): from app.serializers import TwoFactorAuthenticationSerializer return TwoFactorAuthenticationSerializer().get_token(user).access_token class AssetGraphQLTestCase(TestCase): client = Client(schema) print("outside------------------", type(client)) print("outside------------------", dir(client)) @classmethod def setUpTestData(cls): print("Setting up test data-------------------------------") cls.client = Client(schema) cls.user = constants.TEST_USER cls.organization = constants.TEST_ORGANIZATION cls.asset_1 = constants.TEST_ASSET_1 cls.headers = { "Content-Type": "application/json", "HTTP_AUTHORIZATION":generate_token(cls.user) } print("--------------------------------",type(cls.client)) print("--------------------------------",dir(cls.client)) def test_all_asset(self): print("Testing-------------------------------------------") response_data = self.client.execute(query=constants.GRAPHQL_ASSET_QUERY, varaibles=constants.QUERY_VARIABLES, headers=self.headers) print(response_data) print(response_data['data']) self.assertEqual(response_data.status_code, 200) self.assertEqual(response_data['data'], 'Expected value')
错误输出
Setting up test data------------------------------- -------------------------------- <class 'graphene.test.Client'> -------------------------------- ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'execute', 'execute_async', 'execute_options', 'format_error', 'format_result', 'schema'] Testing------------------------------------------- E ====================================================================== ERROR: test_all_asset (app.graphql.tests.test_assets_graphql_fix.AssetGraphQLTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/app/graphql/tests/test_assets_graphql_fix.py", line 41, in test_all_asset response_data = self.client.execute(query=constants.GRAPHQL_ASSET_QUERY, varaibles=constants.QUERY_VARIABLES, headers=self.headers) AttributeError: 'Client' object has no attribute 'execute' ---------------------------------------------------------------------- Ran 1 test in 0.009s FAILED (errors=1) Destroying test database for alias 'default'... root@b026e124367f:/app#
解决方案
核心原因
这是命名冲突导致的:Django的TestCase类自带一个client属性,是Django原生的测试客户端(django.test.Client)。你在类中定义的graphene.test.Client实例会被Django测试框架覆盖,测试方法中调用的self.client实际是Django的客户端,而非你初始化的graphene客户端,自然没有execute方法。
修复步骤
重命名graphene客户端变量,避免和Django自带的
client冲突,比如改成graphql_client:class AssetGraphQLTestCase(TestCase): graphql_client = Client(schema) @classmethod def setUpTestData(cls): print("Setting up test data-------------------------------") cls.graphql_client = Client(schema) # 其余代码不变修改测试方法中的调用逻辑,使用新的变量名:
def test_all_asset(self): print("Testing-------------------------------------------") # 修正参数拼写错误:varaibles → variables response_data = self.graphql_client.execute(query=constants.GRAPHQL_ASSET_QUERY, variables=constants.QUERY_VARIABLES, headers=self.headers) print(response_data) print(response_data['data']) # 移除错误的status_code断言:graphene的execute返回字典,无此属性 # self.assertEqual(response_data.status_code, 200) # 可添加错误检查替代: self.assertNotIn('errors', response_data) self.assertEqual(response_data['data'], 'Expected value')额外修正点:
- 修复参数拼写错误:
varaibles改为variables - graphene的
Client.execute返回的是解析后的GraphQL结果字典,不是Django的HttpResponse,因此不存在status_code属性,需移除对应断言,可通过检查结果中是否存在errors字段判断请求是否成功。
- 修复参数拼写错误:
内容的提问来源于stack exchange,提问作者Parsenjit Kumar
相关产品推荐
相关产品推荐

