React Native测试问题:Nock模拟API后测试不生效
问题:React Native测试中Nock模拟API未生效,组件无法渲染数据
我用React Native做屏幕测试,借助Nock模拟API响应。调用API后组件应该展示文本字段,这个功能在应用里正常运行,但测试始终通不过。
组件代码
export const CreationPage = () => { const [publicSuites, setPublicSuite] = useState<Suite[]>([]) useEffect(() => { axios.get('http://localhost:8080/api/suites').then((response) => { console.log('It worked !', response.data) setPublicSuite(response.data) }, (error) => { console.log('Oups something went wrong :', error) }) }, []) return ( <View> {publicSuites.map((suite) => <Card key={suite.title}> <Text>{suite.title}</Text> </Card> )} </View> ) }
测试代码
it("should display public & private (hidden but visible in DOM) elements at launch", async () => { render(<CreationPage/>); nock('http://localhost:8080') .get('/api/suites') .reply(200, [{title: "Public Suite Test"}]) await waitFor(() => { expect(screen.getByText("Public Suite Test")).toBeTruthy() }) });
日志信息
console.log Oups something went wrong : AxiosError { port: 8080, address: '127.0.0.1', syscall: 'connect', code: 'ECONNREFUSED', ... Error: Unable to find an element with text: Public Suite Test
解决方案
1. 调整Nock的设置顺序
问题核心是先渲染组件,后设置Nock拦截,导致组件的useEffect在Nock生效前就发起了真实的API请求,自然会出现连接拒绝的错误。
修改测试代码,先设置Nock拦截,再渲染组件:
it("should display public & private elements at launch", async () => { // 先配置Nock拦截请求 nock('http://localhost:8080') .get('/api/suites') .reply(200, [{title: "Public Suite Test"}]) // 再渲染组件 render(<CreationPage/>); await waitFor(() => { expect(screen.getByText("Public Suite Test")).toBeTruthy() }) });
2. 改用axios-mock-adapter(更适配React Native)
Nock默认拦截的是Node.js的http模块,但React Native中的Axios可能使用原生网络请求,导致Nock无法拦截。改用axios-mock-adapter可以直接拦截Axios的请求,兼容性更好:
步骤1:安装依赖
npm install axios-mock-adapter --save-dev
步骤2:修改测试代码
import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; it("should display public & private elements at launch", async () => { // 创建Axios实例的mock适配器 const mock = new MockAdapter(axios); // 配置GET请求的模拟响应 mock.onGet('http://localhost:8080/api/suites').reply(200, [{title: "Public Suite Test"}]); render(<CreationPage/>); await waitFor(() => { expect(screen.getByText("Public Suite Test")).toBeTruthy() }) });
内容的提问来源于stack exchange,提问作者Antoine Grenard
相关产品推荐
相关产品推荐

