【问题标题】:Cypress: Stub response for same route with three different responses赛普拉斯:具有三个不同响应的相同路由的存根响应
【发布时间】:2018-12-06 15:27:41
【问题描述】:

我在应用程序中有一个端点。我们为每个请求使用相同的 api,并在参数中使用不同的操作。

网址:

/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 的问题是您只能为路由指定一个响应,而处理此问题的其他方法是发出顺序请求(我们不能这样做)

即使我们将响应写成一个函数,它也只会被调用一次。

关于我们如何根据有效负载模拟数据有什么想法吗?

【问题讨论】:

  • 抱歉,不明白每个请求​​是否有一个查询字符串或其他使它们独一无二的东西。动作是否在正文中进行?
  • 刚刚使用更多示例有效负载编辑了问题。是的,有效负载中的操作对于每个请求都是不同且唯一的
  • 我将建议将响应编写为按顺序返回 3 个有效负载之一的函数,直到我读到您的最后一行。我想你可能是 SOL。

标签: javascript ui-automation cypress


【解决方案1】:

我遇到了完全相同的问题,发现@Richard Matsen 的答案非常有用,但是当使用whitelist 选项时,无法访问proxy.request,它返回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'
      : ''
  }
})

【讨论】:

  • 您在白名单回调中访问代理时一定做错了,因为它在我的测试中有效。
  • 这比使用白名单要好,白名单是用来过滤的,感觉有点hacky。我尝试更改 onRequestonResponse 中的响应(无济于事),但没想到在那里应用 URL 参数。
  • 那么在请求url中设置了这个参数之后,然后呢?我仍然无法使用cy.route({ url: '...?balance' }).as('balance'),因为赛普拉斯找不到匹配项?
  • @AicoKleinOvink 你能做到吗?我已经完成了所有步骤,但由于请求没有附加查询字符串,因此 cypress 无法匹配!
【解决方案2】:

我做了一项肮脏的工作,但我不喜欢它,但我别无选择。

我只是将所有响应合并到同一个响应中。

我的模拟回复

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

每个响应处理程序只处理它感兴趣的部分,如果其中一个响应是数组,我们需要将其更改为对象。

我会寻找更好的解决方法。

【讨论】:

    【解决方案3】:

    这是另一个技巧。它依赖于您的 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 )
    

    【讨论】:

      【解决方案4】:

      如果有人提出这个问题,我可能发现了另一个对我有用的 hack(我正在使用 unfetch polyfill 来解决 fetch 请求和 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
              });
            }
          }
        },
      });

      【讨论】:

        猜你喜欢
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多