【全栈React】第25天: 使用Enzyme做更好的测试
今天,我们将看看一个由Airbnb所维护的开源库,名为Enzyme,使得测试变得简单易用。 昨天我们使用了 我们在测试我们的 使用Enzyme我们将使用Enzyme,使这些测试更容易写和更可读。 昨天,我们写了我们的第一个测试如下: import React from 'react'; import TestUtils from 'react-addons-test-utils'; import Timeline from '../Timeline'; describe('Timeline',() => { it('wraps content in a div with .notificationsFrame class',() => { const wrapper = TestUtils.renderIntoDocument(<Timeline />); TestUtils .findRenderedDOMComponentWithClass(wrapper,'notificationsFrame'); }); }) 虽然这是可行的,但它不是世界上最容易阅读的测试。当用Enzyme我们重写它时让我们看看这个测试的样子。 我们可以只测试组件的输出,而不是用Enzyme来测试完整的组件树。将不渲染任何组件的子级。这称为 浅 渲染。 Enzyme使浅渲染超容易。我们将使用Enzyme导出的 让我们更新 import React from 'react'; import { shallow } from 'enzyme'; describe('Timeline',() => { it('wraps content in a div with .notificationsFrame class',() => { // our tests }); })
> const renderer = ReactTestUtils.createRenderer(); > renderer.render(<Timeline />) > const result = renderer.getRenderOutput(); > 现在,为了渲染我们的组件,我们可以使用 整个断言包括两行: import React from 'react'; import { shallow,mount } from 'enzyme'; import Timeline from '../Timeline'; describe('Timeline',() => { let wrapper; it('wraps content in a div with .notificationsFrame class',() => { wrapper = shallow(<Timeline />); expect(wrapper.find('.notificationsFrame').length).toEqual(1); }); it('has a title of Timeline',() => { wrapper = mount(<Timeline />) expect(wrapper.find('.title').text()).toBe("Timeline") }) describe('search button',() => { let search; beforeEach(() => wrapper = mount(<Timeline />)) beforeEach(() => search = wrapper.find('input.searchInput')) it('starts out hidden',() => { expect(search.hasClass('active')).toBeFalsy() }) it('becomes visible after being clicked on',() => { const icon = wrapper.find('.searchIcon') icon.simulate('click') expect(search.hasClass('active')).toBeTruthy() }) }) describe('status updates',() => { it('has 4 status updates at minimum',() => { wrapper = shallow(<Timeline />) expect( wrapper.find('ActivityItem').length ).toBeGreaterThan(3) }) }) }) 我们可以使用 yarn test
我们的测试通过,并且更易于阅读和维护。 让我们继续写断言,从我们昨天开始的假设列表中抽取。我们将首先构建我们的测试套件的其余部分,写出我们的 import React from 'react'; import { shallow } from 'enzyme'; import Timeline from '../Timeline'; describe('Timeline',() => { wrapper = shallow(<Timeline />); expect(wrapper.find('.notificationsFrame').length).toEqual(1); }); it('has a title of Timeline') describe('search button',() => { it('starts out hidden') it('becomes visible after being clicked on') }) describe('status updates',() => { it('has 4 status updates at minimum') }) })
让我们填写这些测试,以便它们通过我们现有的 我们的标题测试比较简单。我们将查找标题元素并确认标题为 我们希望标题可以在 因为我们的
现在让我们填写标题描述: import React from 'react'; import { shallow,() => { wrapper = mount(<Timeline />) // notice the `mount` expect(wrapper.find('.title').text()).toBe("Timeline") }) }) 运行我们的测试,我们将看到这两个期望通过:
接下来,让我们更新我们的搜索按钮测试。我们在这里有两个测试,其中一个要求我们测试一个交互。Enzyme为处理相互作用提供了一个非常干净的界面。让我们来看看如何根据搜索图标编写测试。 同样,由于我们在时间轴中对子元素进行测试,因此我们必须 此外,我们还将使用 describe('Timeline',() => { let wrapper; // ... describe('search button',() => { let search; beforeEach(() => wrapper = mount(<Timeline />)) beforeEach(() => search = wrapper.find('input.searchInput')) // ... }) }) 若要测试是否隐藏了搜索输入,我们只需要知道是否应用了 describe('Timeline',() => { expect(search.hasClass('active')).toBeFalsy() }) it('becomes visible after being clicked on') // ... }) }) 关于第二个测试的棘手部分是,我们需要点击图标元素。在我们看如何做到这一点之前,让我们先找到它。我们可以在包装上的目标通过它的 it('becomes visible after being clicked on',() => { const icon = wrapper.find('.searchIcon') }) 现在,我们有了图标,我们想模拟一个点击元素。回想一下, 我们将在 it('becomes visible after being clicked on',() => { const icon = wrapper.find('.searchIcon') icon.simulate('click') }) 现在我们可以设定一个 it('becomes visible after being clicked on',() => { const icon = wrapper.find('.searchIcon') icon.simulate('click') expect(search.hasClass('active')).toBeTruthy() }) 我们对 describe('status updates',() => { it('has 4 status updates at minimum',() => { wrapper = shallow(<Timeline />) // ... }) }) 现在,我们可以测试 describe('status updates',() => { wrapper = shallow(<Timeline />) expect( wrapper.find('ActivityItem').length ).toBeGreaterThan(3) }) }) 我们现在的整个测试套件如下所示: import React from 'react'; import { shallow,() => { wrapper = shallow(<Timeline />) expect( wrapper.find('ActivityItem').length ).toBeGreaterThan(3) }) }) }) [](#whats-the-deal-with-find)
|