如何在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
相关产品推荐
相关产品推荐

