模拟来自 ServiceObject 的 GraphQL 查询解析器的响应,以防止单元测试中的 API 调用
Mocking response for GraphQL query resolver from ServiceObject to prevent API calls in the UnitTests
假设我有以下服务对象:
class Foo(object):
def bar(self):
return ['foo', 'bar']
这是架构:
import Foo
class Query(graphene.ObjectType):
bar = graphene.List(lambda: graphene.String)
def resolve_bar(self, info):
return Foo().bar()
我正在尝试测试 GraphQL 模式是否在其查询解析器中正确调用方法 bar
。所以,我们在测试中有这段代码:
from MySchema import Query
class TestFooBar(unittest.TestCase):
@patch('Foo')
def test_bar(self, mock_foo):
mock_foo.return_value.bar.return_value = ['baz', 'qux']
my_schema = graphene.Schema(query=Query)
client = Client(self.my_schema)
query = '''
query {
bar()
}
'''
executed = self.client.execute(query)
#some attributes that I want to assert
assertTrue(mock_foo.called) # returns False
为什么我要使用模拟?
在原始 ServiceObject class 中,它对另一个服务进行了一些 API 调用,该服务已经以隔离方式进行了测试。在这种情况下,我只想测试 GraphQL 查询 bar
是否正在调用一个方法,该方法将 return 它的假定对象。
问题
当我在上面的代码中模拟服务对象 returns 的响应,并使 Graphene Client 测试 运行s 查询时,它给了我 'non-mocked'回复。换句话说,它实际上是在调用服务对象 class 提供的原始方法并进行 API 调用 , 不应该被执行。但是,当我实例化和 运行 ServiceObject class 本身时,它被正确地模拟并且 return 是 ['baz', 'qux']
数组,而不是通过 API 调用。
有人知道我做错了什么吗?
或者根本不应该模拟 GraphQL 客户端响应?有什么方法可以代替模拟它吗?
我已经在互联网上搜索过人们是如何做到的,但我无法找到任何可能的解决方案。
所以,问题是:
我的patch
错了。我应该修补调用站点,而不是定义站点。在这种情况下,它将是:@patch('MySchema.Foo')
完成调用站点的模拟。
证明
from MySchema import Query
class TestFooBar(unittest.TestCase):
@patch('MySchema.Foo')
def test_bar(self, mock_foo):
mock_foo.return_value.bar.return_value = ['baz', 'qux']
my_schema = graphene.Schema(query=Query)
client = Client(self.my_schema)
query = '''
query {
bar()
}
'''
executed = self.client.execute(query)
assertTrue(mock_foo().bar.called) # now returns True
感谢 jkimbo 当我在 Graphene-Python Github repository.
中询问时,他救了我
假设我有以下服务对象:
class Foo(object):
def bar(self):
return ['foo', 'bar']
这是架构:
import Foo
class Query(graphene.ObjectType):
bar = graphene.List(lambda: graphene.String)
def resolve_bar(self, info):
return Foo().bar()
我正在尝试测试 GraphQL 模式是否在其查询解析器中正确调用方法 bar
。所以,我们在测试中有这段代码:
from MySchema import Query
class TestFooBar(unittest.TestCase):
@patch('Foo')
def test_bar(self, mock_foo):
mock_foo.return_value.bar.return_value = ['baz', 'qux']
my_schema = graphene.Schema(query=Query)
client = Client(self.my_schema)
query = '''
query {
bar()
}
'''
executed = self.client.execute(query)
#some attributes that I want to assert
assertTrue(mock_foo.called) # returns False
为什么我要使用模拟?
在原始 ServiceObject class 中,它对另一个服务进行了一些 API 调用,该服务已经以隔离方式进行了测试。在这种情况下,我只想测试 GraphQL 查询 bar
是否正在调用一个方法,该方法将 return 它的假定对象。
问题
当我在上面的代码中模拟服务对象 returns 的响应,并使 Graphene Client 测试 运行s 查询时,它给了我 'non-mocked'回复。换句话说,它实际上是在调用服务对象 class 提供的原始方法并进行 API 调用 , 不应该被执行。但是,当我实例化和 运行 ServiceObject class 本身时,它被正确地模拟并且 return 是 ['baz', 'qux']
数组,而不是通过 API 调用。
有人知道我做错了什么吗?
或者根本不应该模拟 GraphQL 客户端响应?有什么方法可以代替模拟它吗?
我已经在互联网上搜索过人们是如何做到的,但我无法找到任何可能的解决方案。
所以,问题是:
我的patch
错了。我应该修补调用站点,而不是定义站点。在这种情况下,它将是:@patch('MySchema.Foo')
完成调用站点的模拟。
证明
from MySchema import Query
class TestFooBar(unittest.TestCase):
@patch('MySchema.Foo')
def test_bar(self, mock_foo):
mock_foo.return_value.bar.return_value = ['baz', 'qux']
my_schema = graphene.Schema(query=Query)
client = Client(self.my_schema)
query = '''
query {
bar()
}
'''
executed = self.client.execute(query)
assertTrue(mock_foo().bar.called) # now returns True
感谢 jkimbo 当我在 Graphene-Python Github repository.
中询问时,他救了我