javascript - 如何使用 Jest 和 Enzyme 验证在 componentDidMount 中调用了 console.log?

标签 javascript reactjs jestjs axios enzyme

我正在尝试测试我的 axios 调用未获得 200 的 HTTP 响应的情况。当 axios 未获得成功的响应时,它会抛出错误。我想验证在这种情况下 console.log 是否被调用两次。

这是我正在测试的类的片段:

class App extends React.Component {
    ...  
    async componentDidMount() {
        let url = "/api/info/tmp"
        try {
            let response = await axios.get(url);
            ...do stuff
            this.setState(...);
        } catch (e) {
            console.log("Could not get " + url);
            console.log(e);
        }
    }
    ...
}

这是我的 Jest 测试的片段

let mockAxios = new MockAdapter(axios);
...
describe("App - componentDidMount() behavior test", () => {
    beforeEach(() => {
        app = shallow(<App />);
    })

    afterEach(() => {
        app = undefined;
        mockAxios.reset();
    });
    ...
    describe("Get " + url + " HTTP response status is not 200", () => {
        beforeAll(() => {
            mockAxios.onGet(url).reply(302, mockData);
        });
        it("Does not set state regardless of response body", () => {
            console.log = jest.fn();
            const state = app.state();
            expect(console.log).toHaveBeenCalledTimes(2);
            expect(state.solutions).toEqual({});
            expect(state.username).toEqual("");
        });
    });
});

我知道console.log = jest.fn() bit 正在做一些事情,因为当我设置它时,控制台不再记录假错误。但是,测试失败,因为 Expected mock function to have been called two times, but it was called zero times.

我尝试移动 console.log = jest.fn()到“beforeEach”、“beforeAll”中,并作为全局变量。

更新

我很确定这与正在发生的所有异步有关。 如果我这样做:

    it("Does not set state regardless of response body", async () => {
        console.log = jest.fn();
        await app.instance().componentDidMount();
        expect(console.log).toHaveBeenCalledTimes(2);

        const state = app.state();
        expect(state.solutions).toEqual({});
        expect(state.username).toEqual("");
    });

然后测试仍然失败但是我的原因改变了:Expected mock function to have been called two times, but it was called four times.现在我只想弄清楚为什么它被调用四次而不是两次。

更新2

我明白为什么 console.log 被调用了 4 次!现在我只需要弄清楚应该如何重构我的测试。 如果我注释掉我的 Jest 模拟,甚至整个单元测试

    it("Does not set state regardless of response body", async () => {
        //const state = app.state();
        //expect(state.solutions).toEqual({});
        //expect(state.username).toEqual("");
        //expect(console.log).toHaveBeenCalledTimes(2);
    });

然后我可以在控制台中算出确实已经有两个不同的 console.log 调用。 shallow(<App />)必须已经在调用componentDidMount()或者其他的东西。当我添加app.instance().componentDidMount()时,我可以直观地看到它正在记录 4 次。

最佳答案

更新答案

由于您似乎已经知道自己在使用模拟做什么,因此问题可能与 componentDidMount() 有关。 .

我相信您调用shallow(<App />)已经调用应用程序的componentDidMount()一次(这意味着您的 console.log 将被调用两次)。

然后,您随后调用app.instance().componentDidMount() - 也就是说,您调用componentDidMount() 再次(这意味着您的 console.log 将再次被调用两次)。

所以,总共... 4 次调用 console.log .

希望能为您指明正确的方向...

原始答案

实际上,您的问题看起来与[这个关于如何"How to mock console when it is used by a third-party library?"的StackOverFlow问题]非常相似。

您可以使用Jest mock functionsspyOn global.console对象。

例如,您的测试可能如下所示:


// Setup jest to spy on the console
const consoleSpy = jest.spyOn(global.console, 'log')

describe('App - componentDidMount() behavior test', () => {
  beforeEach(() => {
    jest.resetAllMocks()  // reset your consoleSpy state back to initial
    app = shallow(<App />)
  })

  ...

      it('Does not set state regardless of response body', () => {
        const spy = jest.spyOn(global.console, 'log')
        const state = app.state()
        expect(consoleSpy).toHaveBeenCalledTimes(2)
        expect(state.solutions).toEqual({})
        expect(state.username).toEqual('')
      })
  ...

关于javascript - 如何使用 Jest 和 Enzyme 验证在 componentDidMount 中调用了 console.log?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54798632/

相关文章:

javascript - 在 resolve 中返回另一个异步函数

javascript - React 中的 SVG 操作

arrays - React 测试库 - 在 fireEvent 之后使用 'await wait()'

reactjs - 用于脚本加载的模拟实用程序函数

javascript - 让 RegExp.test() 对 null 值返回 false 的更简单方法?

javascript - 有人可以用 JavaScript 解释这种函数包装语法吗?

javascript - React Native错误-找不到变量:NameFields

javascript - React 组件拥有对象

javascript - 使用 bootstrap-vue 运行 jest

javascript - 当 onmouseover 显示隐藏的 div 时,如何阻止此跨度消失?