简体   繁体   English

赛普拉斯:对具有三种不同响应的同一路由的存根响应

[英]Cypress: Stub response for same route with three different responses

I have a single endpoint in the application.我在应用程序中有一个端点。 We hit the same api for each request with different action in the params.我们在参数中使用不同的操作为每个请求命中相同的 api。

URL:网址:

/application/api

Sample Request Payload 1:示例请求负载 1:

{
  "action": "CARD_TRANSACTION_HISTORY",
  "data": {
    "date_from": "2018-12-01",
    "date_to": "2018-12-31",
    "total": 5
  },
  "meta": {}
}

Sample Request Payload 2:示例请求负载 2:

{
  "action": "CARD_BALANCE",
  "data": {
    "date_from": "2018-12-01",
    "date_to": "2018-12-31",
    "total": 5
  },
  "meta": {}
}

Sample Request Payload 3:示例请求负载 3:

{
  "action": "CURRENCY_RATES",
  "data": {
    "date_from": "2018-12-01",
    "date_to": "2018-12-31",
    "total": 5
  },
  "meta": {}
}

the action in above request changes for different requests.上述请求中的操作会根据不同的请求而变化。

When the dashboard page is loaded, we trigger 3 concurrent AJAX POST requests with different actions.加载仪表板页面时,我们会触发 3 个具有不同操作的并发AJAX POST 请求。

Problem with cypress is you can only specify one response for a route, and other way to handle this is make sequential requests (which we can't do) cypress 的问题是您只能为路由指定一个响应,而处理此问题的另一种方法是发出顺序请求(我们不能这样做)

Even if we write response as a function it gets called only once.即使我们将响应写成一个函数,它也只会被调用一次。

Any ideas on how we can mock data on the basis of payload?关于我们如何根据有效载荷模拟数据有什么想法吗?

I had the exact same problem and found @Richard Matsen's answer very useful, however when using the whitelist option it isn't possible to access proxy.request , which returns undefined .我遇到了完全相同的问题,发现@Richard Matsen 的回答非常有用,但是当使用whitelist选项时,无法访问proxy.request ,它返回undefined But if you use onRequest instead of whitelist , you can access the request and thus implement any action depending on that request's body.但是,如果您使用onRequest而不是whitelist ,您可以访问该请求,从而根据该请求的主体执行任何操作。

So this should work:所以这应该有效:

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'
      : ''
  }
})

I did one dirty work around that worked, I didn't like it but I am out of options.我做了一项可行的肮脏工作,我不喜欢它,但我别无选择。

I simply combined all the responses in the same response.我只是将所有响应合并为同一个响应。

My Mock Response我的模拟回应

{
  balance: {..},
  transactionHistory: {..},
  currencyRates: {..}
}

The each response handler simply processes part it is interested in, if one of the response is array, we'll need to change it to an object.每个响应处理程序只处理它感兴趣的部分,如果其中一个响应是数组,我们需要将其更改为一个对象。

I'll be on a lookout for a better work around.我会寻找更好的解决方法。

Here is another hack.这是另一个技巧。 It relies on your api ignoring url parameters and that the cy.server whitelist function is called before the request is made.它依赖于您的 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 )

if anyone comes to this question I probably found another hack, that worked for me (I'm using unfetch polyfill to work around fetch requests and cypress) - here is the code for one route.如果有人提出这个问题,我可能会发现另一个 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 }); } } }, });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM