【问题标题】:Best way to mock authenticated (auth0) API calls in Cypress在 Cypress 中模拟经过身份验证的 (auth0) API 调用的最佳方法
【发布时间】:2023-02-16 07:58:44
【问题描述】:

我有一个常规的单页应用程序 (Vue),它通过 auth0 进行身份验证并生成一个令牌,该令牌由 API 调用的后端进行验证。

我想使用 cypress 测试 vue 应用程序。

有各种“官方”策略(即每次通话都登录或使用会话并登录一次)。

https://auth0.com/blog/end-to-end-testing-with-cypress-and-auth0/ https://docs.cypress.io/guides/testing-strategies/auth0-authentication

我只能找到一个关于存根 auth0 的资源,而不是实际发送令牌请求 - https://github.com/auth0/auth0-spa-js/issues/210

我通过关注另一篇 Stackoverflow 帖子 - How to test single page application with Cypress and Auth0 到达了上述链接。

我只有很少的经验,但存根解决方案似乎更接近测试驱动开发的最佳实践。

我想问问为什么它似乎不那么受欢迎,如果我错过了“实际 auth0 调用”选项背后的真正原因。

谢谢你!

【问题讨论】:

  • 为什么你认为这是在打桩(甚至是“打桩”)?所有方法都具有相同的模式 - 获取真正的令牌并将其保存到适当的存储空间。您别无选择,因为身份验证旨在避免欺骗。如果您可以在测试中存根,请不要使用 - 这不好。
  • 感谢你的回复。我不打算使用“假”令牌来实际访问 API。这个想法是使用 cypress 来拦截 auth0 身份验证,这样我们就可以模拟用户登录。然后拦截(使用用户令牌)API 调用。
  • 好吧,我被标题中的“mock”这个词和我认为是“stubbing”这个词的错误类型的“stabbing”这个词所愚弄了。

标签: cypress auth0


【解决方案1】:

这就是我在 React 中解决这个问题的方法:

1 - 创建一个登录命令:

// cypress/support/commands.js

Cypress.Commands.add('A0login', () => {
  Cypress.log({
    name: 'loginViaAuth0',
  })
  const audience = Cypress.env('auth_audience')
  const client_id = Cypress.env('auth_client_id')
  const scope = 'openid email profile offline_access'

  const options = {
    method: 'POST',
    url: Cypress.env('auth_url'),
    body: {
      grant_type: 'http://auth0.com/oauth/grant-type/password-realm',
      realm: 'Username-Password-Authentication',
      username: Cypress.env('DEFAULT_USER'),
      password: Cypress.env('DEFAULT_PASSWORD'),
      audience,
      scope,
      client_id,
      client_secret: Cypress.env('auth_client_secret'),
    },
  }

  cy.request(options).then(({ body }) => {
    const claims = jwt.decode(body.id_token)
    const { nickname, name, picture, updated_at, sub, exp } = claims
    const { access_token, id_token, token_type, expires_in, refresh_token } =
      body

    const item = {
      body: {
        access_token,
        audience,
        client_id,
        id_token,
        oauthTokenScope: scope,
        expires_in,
        refresh_token,
        scope,
        token_type,
        decodedToken: {
          claims,
          user: {
            nickname,
            name,
            picture,
            updated_at,
            sub,
          },
        },
      },
      expiresAt: exp,
    }

    window.localStorage.setItem(
      `@@auth0spajs@@::${Cypress.env('auth_client_id')}::${Cypress.env(
        'auth_audience',
      )}::openid email profile offline_access`,
      JSON.stringify(item),
    )
  })
})

此命令发出获取令牌的请求,该令牌稍后被解码并存储在本地存储中。

2 - 您需要将 Auth0 缓存位置设置为“localstorage” 3 - 只需在每个测试服之前执行登录并保留 localStorage:

  before(() => {
    cy.A0login()
    cy.visit('/')
    cy.saveLocalStorage()
  })

  beforeEach(() => {
    cy.restoreLocalStorage()
  })

  afterEach(() => {
    cy.saveLocalStorage()
  })

在我的例子中,cy.saveLocalStorage()cy.restoreLocalStorage() 都是自定义命令。

您可能会发现的唯一问题是此身份验证是通过“用户名密码”进行的,但如果您只想测试应用程序和组件的功能,那不是什么大问题。

【讨论】:

    猜你喜欢
    • 2021-07-17
    • 2015-04-23
    • 2013-10-27
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 2017-01-14
    • 1970-01-01
    相关资源
    最近更新 更多