You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Detox中mock GoogleSignin.isSignedIn() 完成React Native测试

Detox测试中Mock GoogleSignin相关方法的实现方案

Detox是端到端黑盒测试工具,要mock原生模块方法,最常用的是通过Metro打包别名替换依赖实现,具体步骤如下:

步骤1:创建mock模块实现

在项目根目录新建mock目录,创建对应模块的mock文件 mocks/@react-native-google-signin/google-signin.js,写入以下内容:

// 预设的测试用户信息,可根据需求修改
const mockTestUser = {
  user: {
    id: 'test_001',
    email: 'test@demo.com',
    givenName: 'Test',
    familyName: 'User',
    photo: 'https://demo.com/avatar.png'
  },
  idToken: 'fake_test_id_token',
  serverAuthCode: 'fake_auth_code'
}

const GoogleSigninMock = {
  // 暴露修改mock返回值的方法,适配不同测试场景
  __mockSetSignedIn: (isSigned) => {
    GoogleSigninMock.isSignedIn.mockResolvedValue(isSigned)
  },
  __mockSetUserInfo: (userInfo) => {
    GoogleSigninMock.signInSilently.mockResolvedValue(userInfo)
    GoogleSigninMock.signIn.mockResolvedValue(userInfo)
  },
  isSignedIn: jest.fn().mockResolvedValue(false),
  signInSilently: jest.fn().mockResolvedValue(mockTestUser),
  signIn: jest.fn().mockResolvedValue(mockTestUser),
  // 业务中用到的其他GoogleSignin方法可在此处补充对应mock实现
}

export default GoogleSigninMock

步骤2:配置Metro打包别名

修改项目的 metro.config.js 配置,在Detox测试构建时自动替换官方模块为我们写的mock文件:

const path = require('path')
const isDetoxBuild = process.env.DETOX_TEST === 'true'

module.exports = {
  // 保留你原有配置的其他内容,只修改resolver部分
  resolver: {
    extraNodeModules: isDetoxBuild ? {
      '@react-native-google-signin/google-signin': path.resolve(__dirname, 'mocks/@react-native-google-signin/google-signin.js')
    } : {}
  }
}

步骤3:增加测试用控制入口

在React Native应用的入口文件(比如App.js/index.js)中增加仅在Detox测试环境生效的全局控制方法,方便测试用例动态修改mock返回值:

if (process.env.DETOX_TEST === 'true') {
  global.detoxTestControls = {
    setGoogleSignedStatus: (isSigned) => {
      require('@react-native-google-signin/google-signin').default.__mockSetSignedIn(isSigned)
    },
    setGoogleMockUser: (userInfo) => {
      require('@react-native-google-signin/google-signin').default.__mockSetUserInfo(userInfo)
    }
  }
}

步骤4:编写Detox测试用例

跑测试时通过环境变量触发mock构建,然后在测试用例中通过executeJavaScript调用全局控制方法切换场景:

// e2e/login.test.js
describe('谷歌登录流程测试', () => {
  beforeEach(async () => {
    // 每次用例启动新实例避免缓存
    await device.launchApp({ newInstance: true })
  })

  it('未登录场景下走主动登录流程', async () => {
    // 设置为未登录状态
    await device.executeJavaScript(`
      global.detoxTestControls.setGoogleSignedStatus(false)
    `)
    await element(by.id('google_login_btn')).tap()
    // 验证登录成功后展示用户信息
    await expect(element(by.id('user_email_text'))).toHaveText('test@demo.com')
  })

  it('已登录场景下走静默登录流程', async () => {
    // 设置为已登录状态
    await device.executeJavaScript(`
      global.detoxTestControls.setGoogleSignedStatus(true)
    `)
    await element(by.id('google_login_btn')).tap()
    // 验证静默登录生效,没有跳转谷歌授权页,直接展示用户信息
    await expect(element(by.id('user_email_text'))).toHaveText('test@demo.com')
  })
})

运行测试

启动测试时传入环境变量即可启用mock:

DETOX_TEST=true detox test --configuration ios.release

注意事项

  • 生产构建时不要传入DETOX_TEST环境变量,避免mock代码被打包到生产包
  • 如果业务中用到了GoogleSignin的其他方法,直接在mock文件中补充对应的jest mock实现即可

内容的提问来源于stack exchange,提问作者Rama Biswas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 01:45:04