简体   繁体   English

react-testing-library Mocking Fat Arrow 组件方法

[英]react-testing-library Mocking Fat Arrow Component Methods

I'm trying to create a unit test for testing a React component with fat arrow function methods.我正在尝试创建一个单元测试来测试带有粗箭头 function 方法的 React 组件。 I'm trying to mock these methods in the unit test via react-testing-library + jest, but with no success我试图通过 react-testing-library + jest 在单元测试中模拟这些方法,但没有成功

I was not able to do the mocking as the jest.spyOn throws an error saying that the method is not a function我无法执行 mocking,因为 jest.spyOn 会抛出一个错误,指出该方法不是 function

This is breaking the encapsulation philosophy behind react-testing-library.这打破了 react-testing-library 背后的封装理念。 You shouldn't be concerned with mocking internal methods;你不应该关心 mocking 内部方法; instead, focus on UI changes the user can observe, and test for those.相反,专注于用户可以观察到的 UI 变化,并对其进行测试。

Check out the Guiding Principles in the docs for more context.查看文档中的指导原则以获取更多上下文。

You cannot spy on a react component function. I was also trying to make that work.你不能监视反应组件 function。我也试图让它工作。 I wanted to be sure, so I wrote a few simplistic components and tests, and tried all possible configurations, including named versus default exports and a little import * as Component so one can then do const spy = jest.spyOn(Component, 'default') .我想确定,所以我写了一些简单的组件和测试,并尝试了所有可能的配置,包括命名导出和默认导出以及一些import * as Component这样就可以执行const spy = jest.spyOn(Component, 'default') It.它。 Doesn't.没有。 Work.工作。 I would love to be wrong about this, but after all that I read today, I do not think so.我很想在这一点上是错误的,但在我今天读完之后,我不这么认为。 This appears to be intentional on the part of RTL, and exactly for the reason explained by @dangerismycat.这似乎是 RTL 有意为之,并且正是出于@dangerismycat 所解释的原因。

You can however, auto-mock a component like so:但是,您可以像这样自动模拟一个组件:

jest.mock('./path-to-component')

Or if you want to mock only some of the named exports, you could write:或者如果你只想模拟一些命名的导出,你可以写:

const mockExport = jest.fn()
jest.mock('./path-to-component', () => {
  const actual = jest.requireActual('./path-to-component')
  return {
    ...actual,
    namedExport: mockExport,
  }
})

You can even do this with default exports, though there are caveats .您甚至可以使用默认导出来执行此操作,但有一些注意事项

Between auto-mock v. spy approaches, one notable difference is that the auto-mocked component cannot be restored to it's original pre-mocked state like a spy can.在 auto-mock 和 spy 方法之间,一个显着的区别是自动模拟的组件不能像间谍一样恢复到它原来的预模拟 state。 A spy can also stay true to its name, only spying on the normal functioning of the component for use with assertions.间谍也可以名副其实,只监视组件的正常运行以用于断言。 It can also be chained with a .mockImplementation , or .mockReturnValue , etc. With a working spy you can do all of these things in the same file;它也可以与.mockImplementation.mockReturnValue等链接在一起。使用一个工作间谍,您可以在同一个文件中完成所有这些事情; just not with a modern react function component.只是不使用现代 React function 组件。

The auto-mock does have some cool features, as illustrated by the snippets above, and certainly more I have yet to discover.自动模拟确实有一些很酷的功能,如上面的片段所示,当然还有更多我尚未发现的功能。 Hoisting the auto-mocks above the imports in particular is an interesting touch.将 auto-mocks 提升到 imports 之上尤其是一种有趣的做法。 Without a doubt mocks are an essential tool for anyone working on a massive application.毫无疑问,模拟是任何从事大型应用程序工作的人的必备工具。

While it is not technically difficult to understand the argument for writing tests from a user perspective, and it has fundamentally changed the way I think about writing tests as a result of this quandary, this is still an unnecessary limitation.虽然从用户角度理解编写测试的论点在技术上并不困难,并且由于这种困境,它从根本上改变了我思考编写测试的方式,但这仍然是一个不必要的限制。 There can be thousands of files in one single application if it lives long enough, and the redux store would be totally bloated in an app like that.如果一个应用程序存在时间足够长,它可以有数千个文件,而 redux 商店在这样的应用程序中将完全膨胀。 There may be remnants of enzyme, too, and plenty of class components, In that scenario, so much boilerplate is required just to test a simple behavior.也可能有残留的酶和大量的 class 组件,在那种情况下,仅仅测试一个简单的行为就需要这么多样板。 and mocks are indispensable with managing that.模拟对于管理它是必不可少的。

Furthermore, there is another fun trend cropping up where components are wrapped with a container that is responsible for massaging all of its data into displayable dates and strings and such.此外,还有另一个有趣的趋势出现,其中组件用一个容器包装,该容器负责将其所有数据按摩到可显示的日期和字符串等中。 This Separation Of Concerns™ is quite nice.这种关注点分离™ 非常好。 The main component is only responsible for keeping track of showing (or hiding) different elements under certain conditions.主要组件只负责跟踪在特定条件下显示(或隐藏)不同的元素。 Unfortunately, the tight coupling between them conflicts with RTL's dictation of how one should test react.不幸的是,它们之间的紧密耦合与 RTL 对测试反应方式的规定相冲突。

Finally, there is one more aspect of this approach which feels unnecessarily restrictive.最后,这种方法还有一个方面让人感觉受到了不必要的限制。 There is more at work in an application than what the user can see, so this user-only perspective seems shortsighted.应用程序中的工作比用户可以看到的要多,因此这种仅用户的观点似乎是短视的。

In conclusion, I recommend not fighting the opinionated framework.总之,我建议不要与自以为是的框架作斗争。 Like a casino, the framework always wins.就像赌场一样,框架总是赢家。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM