实际交互与模拟 MockService 的预期交互不匹配
Actual interactions do not match expected interactions for mock MockService
我是 python 和合同测试的新手。我正在尝试使用 pact-python
.
测试我的消费者应用程序
这是测试文件test_posts_controller.py
import unittest
import atexit
from pact import Consumer, Provider, Term
import requests
pact = Consumer('Consumer').has_pact_with(Provider('Provider'))
pact.start_service()
atexit.register(pact.stop_service)
class GetPostsContract(unittest.TestCase):
def test_get_all_posts(self):
expected = {
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
(pact
.given('posts exist')
.upon_receiving('a request for post by id')
.with_request('GET', '/posts/1')
.will_respond_with(200, body=expected))
with pact:
result = requests.get('https://jsonplaceholder.typicode.com/posts/1')
self.assertEqual(result.json(), expected)
我在这里尝试点击 JSONPlaceholder。
我正在使用 pytest
命令来 运行 测试。
但我收到以下错误。我不知道我错过了什么。
self = <pact.pact.Pact object at 0x10cc8c8d0>
def verify(self):
"""
Have the mock service verify all interactions occurred.
Calls the mock service to verify that all interactions occurred as
expected, and has it write out the contracts to disk.
:raises AssertionError: When not all interactions are found.
"""
self._interactions = []
resp = requests.get(
self.uri + '/interactions/verification',
headers=self.HEADERS)
> assert resp.status_code == 200, resp.text
E AssertionError: Actual interactions do not match expected interactions for mock MockService.
E
E Missing requests:
E GET /posts/1
E
E See pact-mock-service.log for details.
venv/lib/python3.7/site-packages/pact/pact.py:209: AssertionError
我也尝试了 pact.setup()
和 pact.verify()
,但我仍然遇到同样的错误。有人可以帮我解决这个问题吗?
而且它也不会创建 pactfile。我必须设置哪些东西?
Pact 告诉您交互从未被触发。你永远不会在契约模拟服务器上调用 GET /posts/1
,因此当你尝试验证它时,它会说它缺少交互并且因为它失败而不是生成契约文件。
除非 https://jsonplaceholder.typicode.com/posts/1
指向协议模拟服务(我猜它不是),否则这将不起作用。无论它位于哪个端口(通常在本地主机上:),都是您需要点击的端口。
代替您执行的代码,从协议本身获取基本 URI:
with pact:
result = requests.get(pact.uri + '/posts/1')
self.assertEqual(result.json(), expected)
pact.verify()
如何找出它发生的原因
AssertionError: Actual interactions do not match expected interactions for mock MockService.
^ 此错误表示 pact 模拟未收到 Pact 测试中描述的交互。
E Missing requests:
E GET /posts/1
^ 这部分表示模拟没有收到 /posts/1
的 GET
请求。如果模拟服务器收到了其他请求(例如它没有预料到的 POST
),它们也会在此处列出。
因此,我们知道在测试期间没有请求到达模拟服务器。
阅读测试的其余部分 class,我们有:
with pact:
result = requests.get('https://jsonplaceholder.typicode.com/posts/1')
这表明测试命中 jsonplaceholder.typicode.com
而不是测试期间设置的模拟。所以,错误是正确的——要修复它,我们需要访问模拟服务器:
如何修复
要解决您的问题,您需要联系 pact 模拟服务器:
with pact:
result = requests.get('https://localhost:1234/posts/1')
(或者您配置 Pact 监听的任何端口)。
您也可以直接从 Pact 获取:
with pact:
result = requests.get(pact.uri + '/posts/1')
如何了解更多
您可能会发现这张消费者测试图很有用(摘自 Pact 文档的 How Pact Works 部分):
你的consumer代码是橙色部分,蓝色部分是Pact提供的mock。
在 Pact 测试期间,消费者不联系实际提供者,它只联系模拟提供者。提供者验证的情况正好相反——只有模拟消费者联系真正的提供者。
这意味着您不需要同时启动消费者和提供者来进行测试。这个优势是合约测试的一大卖点。
可以提供主机名和端口来覆盖默认值
http://localhost:1234 mock-service URL
示例:
pact = Consumer('Consumer').has_pact_with(Provider('Provider'), port='<port>', host_name='<host>')
我是 python 和合同测试的新手。我正在尝试使用 pact-python
.
这是测试文件test_posts_controller.py
import unittest
import atexit
from pact import Consumer, Provider, Term
import requests
pact = Consumer('Consumer').has_pact_with(Provider('Provider'))
pact.start_service()
atexit.register(pact.stop_service)
class GetPostsContract(unittest.TestCase):
def test_get_all_posts(self):
expected = {
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
(pact
.given('posts exist')
.upon_receiving('a request for post by id')
.with_request('GET', '/posts/1')
.will_respond_with(200, body=expected))
with pact:
result = requests.get('https://jsonplaceholder.typicode.com/posts/1')
self.assertEqual(result.json(), expected)
我在这里尝试点击 JSONPlaceholder。
我正在使用 pytest
命令来 运行 测试。
但我收到以下错误。我不知道我错过了什么。
self = <pact.pact.Pact object at 0x10cc8c8d0>
def verify(self):
"""
Have the mock service verify all interactions occurred.
Calls the mock service to verify that all interactions occurred as
expected, and has it write out the contracts to disk.
:raises AssertionError: When not all interactions are found.
"""
self._interactions = []
resp = requests.get(
self.uri + '/interactions/verification',
headers=self.HEADERS)
> assert resp.status_code == 200, resp.text
E AssertionError: Actual interactions do not match expected interactions for mock MockService.
E
E Missing requests:
E GET /posts/1
E
E See pact-mock-service.log for details.
venv/lib/python3.7/site-packages/pact/pact.py:209: AssertionError
我也尝试了 pact.setup()
和 pact.verify()
,但我仍然遇到同样的错误。有人可以帮我解决这个问题吗?
而且它也不会创建 pactfile。我必须设置哪些东西?
Pact 告诉您交互从未被触发。你永远不会在契约模拟服务器上调用 GET /posts/1
,因此当你尝试验证它时,它会说它缺少交互并且因为它失败而不是生成契约文件。
除非 https://jsonplaceholder.typicode.com/posts/1
指向协议模拟服务(我猜它不是),否则这将不起作用。无论它位于哪个端口(通常在本地主机上:),都是您需要点击的端口。
代替您执行的代码,从协议本身获取基本 URI:
with pact:
result = requests.get(pact.uri + '/posts/1')
self.assertEqual(result.json(), expected)
pact.verify()
如何找出它发生的原因
AssertionError: Actual interactions do not match expected interactions for mock MockService.
^ 此错误表示 pact 模拟未收到 Pact 测试中描述的交互。
E Missing requests:
E GET /posts/1
^ 这部分表示模拟没有收到 /posts/1
的 GET
请求。如果模拟服务器收到了其他请求(例如它没有预料到的 POST
),它们也会在此处列出。
因此,我们知道在测试期间没有请求到达模拟服务器。
阅读测试的其余部分 class,我们有:
with pact:
result = requests.get('https://jsonplaceholder.typicode.com/posts/1')
这表明测试命中 jsonplaceholder.typicode.com
而不是测试期间设置的模拟。所以,错误是正确的——要修复它,我们需要访问模拟服务器:
如何修复
要解决您的问题,您需要联系 pact 模拟服务器:
with pact:
result = requests.get('https://localhost:1234/posts/1')
(或者您配置 Pact 监听的任何端口)。
您也可以直接从 Pact 获取:
with pact:
result = requests.get(pact.uri + '/posts/1')
如何了解更多
您可能会发现这张消费者测试图很有用(摘自 Pact 文档的 How Pact Works 部分):
你的consumer代码是橙色部分,蓝色部分是Pact提供的mock。
在 Pact 测试期间,消费者不联系实际提供者,它只联系模拟提供者。提供者验证的情况正好相反——只有模拟消费者联系真正的提供者。
这意味着您不需要同时启动消费者和提供者来进行测试。这个优势是合约测试的一大卖点。
可以提供主机名和端口来覆盖默认值
http://localhost:1234 mock-service URL
示例:
pact = Consumer('Consumer').has_pact_with(Provider('Provider'), port='<port>', host_name='<host>')