酶安装不调用useEffect; react-testing-library渲染未调用useEffect

时间:2020-05-14 22:55:27

标签: reactjs react-hooks enzyme react-testing-library

我正在尝试用酶的支架测试React挂钩。看起来好像没有调用React钩子useEffect。

这是我的功能组件:

export function HelloFetch() {
  type HelloData = { Message: any }
  const initialHelloData : HelloData = { Message: "" };
  const url = `https://localhost:1000/api/hello`;

  const [helloData, setHelloData] = useState(initialHelloData);

  useEffect(() => {
    fetch(
      url,
      {
        method: "GET"
      }
    )
    .then(res  => res.json() )
    .then(response => {
      setHelloData(response)
      console.log(response)
    })
     . catch(error => console.error(error));
  });

  return (
    <div>
        <div>
          <p>Fetch: </p>{helloData.Message}
        </div>
    </div>
  );
}

api应该返回“ hello,world”,这在邮递员中是这样。在浏览器中看起来也不错。

{"Message":"Hello, world"}

这是我的测试代码:

describe('Hello', () => {
    const helloFetchComponent = mount(<HelloFetch />);

    it(' using fetch api should contain "Hello, world"', () => {
      expect(helloFetchComponent.html()).toContain("Hello, world");
    });
}

我收到此错误:

Expected substring: "Hello, world"
Received string:    "<div><div><p>Fetch: </p></div></div>" 

我尝试使用react-testing-library的render方法对其进行测试。

test('renders hello world app', () => {
  const { getByText } = render(
    <HelloFetch />
  );

  expect(getByText('Hello')).toBeInTheDocument();
});

这是我得到的错误:

renders hello world app

    Unable to find an element with the text: Hello. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

<body>
  <div>
    <div>
      <div>
        <p>
          Fetch:
        </p>

      </div>
    </div>
  </div>
</body>

我不确定我错过了什么。

编辑:将我的评论重新发布到@Florian以便进行更好的格式化。

我从获取转到了axios。我有以下内容:

describe('Hello', () => { 
    it(' using axios should contain "mock Hello, world"', () => { 
        const mock = new MockAdapter(axios); 
        const mockData : HelloData = { Message: "mock Hello, world"}; 
        mock.onGet(helloUrl).reply(200, mockData); 
        let component = mount(<HelloAxios />); 
        expect(component.html()).toContain("mock Hello, world"); 
    }) 
}) 

即使api正常运行,该组件也不包含来自api的数据。

以下方法有效:

axios.get(helloUrl).then(function (response) { 
    expect(response.data.html()).toContain("mock Hello, world"); 
});

我不知道如何使mountMockAdapter一起工作。

1 个答案:

答案 0 :(得分:0)

获取在Jest执行测试的Node中不可用。

您不应尝试在单元测试中进行真正的HTTP调用,而应使用Jest出色的工具模拟它们:https://jestjs.io/docs/en/mock-functions.html

或者您也可以使用https://github.com/jefflau/jest-fetch-mock

模拟负责API调用的函数:

import * as ModuleExportingAsyncFunction from 'ModuleExportingAsyncFunction'

const mockedThings = [{...}, {...}];

jest.spyOn(ModuleExportingAsyncFunction, 'getThingsReturnPromise').mockReturnValue(Promise.resolve(mockedThings));

// no more real HTTP calls !