赛普拉斯:对具有三种不同响应的同一路由的存根响应
Cypress: Stub response for same route with three different responses
我在应用程序中只有一个端点。我们在参数中使用不同的操作为每个请求点击相同的 api。
URL:
/application/api
示例请求负载 1:
{
"action": "CARD_TRANSACTION_HISTORY",
"data": {
"date_from": "2018-12-01",
"date_to": "2018-12-31",
"total": 5
},
"meta": {}
}
示例请求负载 2:
{
"action": "CARD_BALANCE",
"data": {
"date_from": "2018-12-01",
"date_to": "2018-12-31",
"total": 5
},
"meta": {}
}
示例请求负载 3:
{
"action": "CURRENCY_RATES",
"data": {
"date_from": "2018-12-01",
"date_to": "2018-12-31",
"total": 5
},
"meta": {}
}
上述请求中的操作会因请求而异。
加载仪表板页面时,我们触发 3 个 并发 AJAX POST 个具有不同操作的请求。
cypress 的问题是您只能为路由指定一个响应,而处理此问题的另一种方法是发出顺序请求(我们不能这样做)
即使我们将响应写成一个函数,它也只会被调用一次。
关于我们如何根据有效负载模拟数据有什么想法吗?
我做了一项肮脏的工作,但它奏效了,我不喜欢它,但我别无选择。
我只是将所有回复合并到同一个回复中。
我的模拟回复
{
balance: {..},
transactionHistory: {..},
currencyRates: {..}
}
每个响应处理程序只处理它感兴趣的部分,如果其中一个响应是数组,我们需要将其更改为对象。
我会寻找更好的解决方法。
这是另一个技巧。它依赖于您的 api 忽略 url 参数,并且 cy.server 白名单函数在发出请求之前被调用。
cy.server({
whitelist: (proxy) => {
proxy.url = proxy.url +
proxy.request.body.action == 'CARD_TRANSACTION_HISTORY' ? '?transactionHistory'
: proxy.request.body.action == 'CARD_BALANCE' ? '?balance'
: proxy.request.body.action == 'CURRENCY_RATES' ? '?currencyRates'
: ''
}
})
const apiMocks = {
balance: {..},
transactionHistory: {..},
currencyRates: {..}
}
cy.route('/application/api?balance', apiMocks.balance).as('balance')
cy.route('/application/api?transactionHistory', apiMocks.transactionHistory)
.as('transactionHistory')
cy.route('/application/api?currencyRates', apiMocks.currencyRates).as('currencyRates')
cy.visit(...)
cy.wait('@balance').then(xhr => //should see correct mock here )
我遇到了完全相同的问题,发现@Richard Matsen 的回答非常有用,但是当使用 whitelist
选项时,无法访问 proxy.request
,returns undefined
。但是,如果您使用 onRequest
而不是 whitelist
,您可以访问该请求,从而根据该请求的主体执行任何操作。
所以这应该有效:
cy.server({
onRequest: (xhr) => {
xhr.url = xhr.url +
xhr.request.body.action == 'CARD_TRANSACTION_HISTORY' ? '?transactionHistory'
: xhr.request.body.action == 'CARD_BALANCE' ? '?balance'
: xhr.request.body.action == 'CURRENCY_RATES' ? '?currencyRates'
: ''
}
})
如果有人提出这个问题,我可能发现了另一个 hack,它对我有用(我使用 unfetch polyfill 来解决获取请求和 cypress)——这是一条路线的代码。
cy.route({
url: '/api/ngfw/devices/search',
method: 'POST',
// Default response, when parametrs doesn't match
response: [],
onResponse: (xhr) => {
xhr.response = { body: [] };
const { body } = xhr.request;
if (body.groupBy) {
const [groupBy] = body.groupBy;
if (groupBy === 'overallColor') {
Object.defineProperty(xhr.xhr, 'responseText', {
// Putting response inside
value: JSON.stringify(mockData.totalsResult),
enumerable: true
});
}
}
},
});
我在应用程序中只有一个端点。我们在参数中使用不同的操作为每个请求点击相同的 api。
URL:
/application/api
示例请求负载 1:
{
"action": "CARD_TRANSACTION_HISTORY",
"data": {
"date_from": "2018-12-01",
"date_to": "2018-12-31",
"total": 5
},
"meta": {}
}
示例请求负载 2:
{
"action": "CARD_BALANCE",
"data": {
"date_from": "2018-12-01",
"date_to": "2018-12-31",
"total": 5
},
"meta": {}
}
示例请求负载 3:
{
"action": "CURRENCY_RATES",
"data": {
"date_from": "2018-12-01",
"date_to": "2018-12-31",
"total": 5
},
"meta": {}
}
上述请求中的操作会因请求而异。
加载仪表板页面时,我们触发 3 个 并发 AJAX POST 个具有不同操作的请求。
cypress 的问题是您只能为路由指定一个响应,而处理此问题的另一种方法是发出顺序请求(我们不能这样做)
即使我们将响应写成一个函数,它也只会被调用一次。
关于我们如何根据有效负载模拟数据有什么想法吗?
我做了一项肮脏的工作,但它奏效了,我不喜欢它,但我别无选择。
我只是将所有回复合并到同一个回复中。
我的模拟回复
{
balance: {..},
transactionHistory: {..},
currencyRates: {..}
}
每个响应处理程序只处理它感兴趣的部分,如果其中一个响应是数组,我们需要将其更改为对象。
我会寻找更好的解决方法。
这是另一个技巧。它依赖于您的 api 忽略 url 参数,并且 cy.server 白名单函数在发出请求之前被调用。
cy.server({
whitelist: (proxy) => {
proxy.url = proxy.url +
proxy.request.body.action == 'CARD_TRANSACTION_HISTORY' ? '?transactionHistory'
: proxy.request.body.action == 'CARD_BALANCE' ? '?balance'
: proxy.request.body.action == 'CURRENCY_RATES' ? '?currencyRates'
: ''
}
})
const apiMocks = {
balance: {..},
transactionHistory: {..},
currencyRates: {..}
}
cy.route('/application/api?balance', apiMocks.balance).as('balance')
cy.route('/application/api?transactionHistory', apiMocks.transactionHistory)
.as('transactionHistory')
cy.route('/application/api?currencyRates', apiMocks.currencyRates).as('currencyRates')
cy.visit(...)
cy.wait('@balance').then(xhr => //should see correct mock here )
我遇到了完全相同的问题,发现@Richard Matsen 的回答非常有用,但是当使用 whitelist
选项时,无法访问 proxy.request
,returns undefined
。但是,如果您使用 onRequest
而不是 whitelist
,您可以访问该请求,从而根据该请求的主体执行任何操作。
所以这应该有效:
cy.server({
onRequest: (xhr) => {
xhr.url = xhr.url +
xhr.request.body.action == 'CARD_TRANSACTION_HISTORY' ? '?transactionHistory'
: xhr.request.body.action == 'CARD_BALANCE' ? '?balance'
: xhr.request.body.action == 'CURRENCY_RATES' ? '?currencyRates'
: ''
}
})
如果有人提出这个问题,我可能发现了另一个 hack,它对我有用(我使用 unfetch polyfill 来解决获取请求和 cypress)——这是一条路线的代码。
cy.route({
url: '/api/ngfw/devices/search',
method: 'POST',
// Default response, when parametrs doesn't match
response: [],
onResponse: (xhr) => {
xhr.response = { body: [] };
const { body } = xhr.request;
if (body.groupBy) {
const [groupBy] = body.groupBy;
if (groupBy === 'overallColor') {
Object.defineProperty(xhr.xhr, 'responseText', {
// Putting response inside
value: JSON.stringify(mockData.totalsResult),
enumerable: true
});
}
}
},
});