Part 2: Jest中对Vue组件的深层渲染

Test Deeply Rendered Vue.js Components in Jest

Jest中对Vue组件的深层渲染

Let’s see how to use vue-test-utils to test a fully rendered component tree.
我们来看一下如何用vue-test-utils来对Vue组件进行组件树级别的模拟渲染

In Write the first Vue.js Component Unit Test in Jest we’ve seen how to use Shallow Rendering to test a component in isolation, preventing the components sub-tree from rendering.
上节中我们看到了如何对Vue组件进行浅渲染,来达到单独对组件文件进行单元测试的目的,以防子组件对父组件渲染污染。

But in some cases, we could want to test components that behave as a group, or molecules as stated in Atomic Design. Keep in mind that this apply to Presentational Components, since they’re unaware of app state and logic. In most case, you’d want to use Shallow Rendering for Container components.
但是有些情况下,我们反而希望组件树形成一个整体来进行测试。这种模式适用于虚拟组件,由于他们并没有对store中的数据和组件中的逻辑造成影响,此时与你大多数情况下希望对跟组件进行浅渲染不同,你想要做的是对组件进行深层渲染。

Adding a Message Component

增加一个Message组件

For the case of a Message and MessageList components, apart from writing their own unit tests, we could want to test them both as a unit as well.
对于Message和MessageList两个组件来说,对其进行独立的单元测试不如将其视为一个整体,进行一次单元测试就够了。

Let’s start by creating components/Message.vue:
现在让我们进入components目录,从创建Message.vue开始:




And update components/MessageList.vue to use it:
然后在MessageList中引入Message组件:




Testing MessageList with Message Component

To test MessageList with Deep Rendering, we just need to use mount instead of shallow in the previously created test/MessageList.test.js:
为了对MessageList进行深层渲染的测试,我们只需要运用mount方法代替shallow方法:

import { mount } from 'vue-test-utils'
import MessageList from '../src/components/MessageList'

describe('MessageList.test.js', () => {
  let cmp

  beforeEach(() => {
    cmp = mount(MessageList, {
      // Beaware that props is overriden using `propsData`
      propsData: {
        messages: ['Cat']
      }
    })
  })

  it('has received ["Cat"] as the message property', () => {
    expect(cmp.vm.messages).toEqual(['Cat'])
  })

  it('has the expected html structure', () => {
    expect(cmp.element).toMatchSnapshot()
  })
})

Btw, have you realized about the beforeEach thing? That’s a very clean way to create a clean component before each test, which is very important in unit testing, since it defines that test shouldn’t depend on each other.
顺便说一句,你有没有注意到代码中的beforeEach方法?如果你寻求一个没有后顾之忧的初始化组件实例的方法,beforeEach就是你想要的,它在单元测试中非常重要,这归功于它使得各个实例之间没有数据污染。

Both mount and shallow use exactly the same API, the difference is in the rendering. I’ll show you progressively the API along in this series.
mount和shallow使用的是同一个API,差别只在于rendering部分。接下来我将向大家演示个中差异。

If you run npm t you’ll see the test are failing because the Snapshot doesn’t match for MessageList.test.js. To regenerate them, run it with -u option:
如果你运行npm t,你会看到测试用例没有被通过,这是因为之前产生的快照跟如今产生的快照不匹配。同样,你可以更新快照来解决这个问题。

npm t -- -u

Then if you open and inspect test/snapshots/MessageList.test.js.snap, you’ll see the class="message" is there, meaning the component has been rendered.
接下来,如果你打开快照目录,查看刚生成的文件,你会看到子组件已经被成功渲染了出来。

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`MessageList.test.js has the expected html structure 1`] = `
  • Cat
`;

Keep in mind to avoid deep rendering when there can be side effects, since the children component hooks, such created and mount will be triggered, and there can be HTTP calls or other side effects there that we don’t want to be called. If you wanna try what I’m saying, add to the Message.vue component a console.log in the created hook:
切记,如果子组件会造成状态改变等副作用时,比如在生命周期钩子中有相关事件被触发,要避免使用深层渲染。如果你不太清楚我说的是哪些事件,你可以在子组件的create钩子中添加一个console.log命令。

export default {
  props: ['message'],
  created() {
    console.log('CREATED!')
  }
}

Then if you run the tests again with npm t, you’ll see the "CREATED!" text in the terminal output. So, be cautious.
然后你执行测试用例时,你会在终端输出的界面上看到打印出来的相关信息,所以,一定要注意这种情况。

你可能感兴趣的:(Part 2: Jest中对Vue组件的深层渲染)