uTools-Manuals/docs/vue/guide/unit-testing.html
2019-04-21 11:50:48 +08:00

125 lines
8.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="content guide with-sidebar unit-testing-guide">
<h1>单元测试</h1>
<blockquote>
<p><a href="https://cli.vuejs.org/zh/" rel="noopener" target="_blank">Vue CLI</a> 拥有开箱即用的通过 <a href="https://github.com/facebook/jest" rel="noopener" target="_blank">Jest</a><a href="https://mochajs.org/" rel="noopener" target="_blank">Mocha</a> 进行单元测试的内置选项。我们还有官方的 <a href="https://vue-test-utils.vuejs.org/zh/" rel="noopener" target="_blank">Vue Test Utils</a> 提供更多详细的指引和自定义设置。</p>
</blockquote>
<h2 id="简单的断言"><a class="headerlink" href="#简单的断言" title="简单的断言"></a>简单的断言</h2><p>你不必为了可测性在组件中做任何特殊的操作,导出原始设置就可以了:</p>
<pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{{ message }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
data () {
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">message</span>: <span class="hljs-string">'hello!'</span>
}
},
created () {
<span class="hljs-keyword">this</span>.message = <span class="hljs-string">'bye!'</span>
}
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
<p>然后随着 Vue 导入组件的选项,你可以使用许多常见的断言 (这里我们使用的是 Jasmine/Jest 风格的 <code>expect</code> 断言作为示例)</p>
<pre><code class="hljs js"><span class="hljs-comment">// 导入 Vue.js 和组件,进行测试</span>
<span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
<span class="hljs-keyword">import</span> MyComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'path/to/MyComponent.vue'</span>
<span class="hljs-comment">// 这里是一些 Jasmine 2.0 的测试,你也可以使用你喜欢的任何断言库或测试工具。</span>
describe(<span class="hljs-string">'MyComponent'</span>, () =&gt; {
<span class="hljs-comment">// 检查原始组件选项</span>
it(<span class="hljs-string">'has a created hook'</span>, () =&gt; {
expect(<span class="hljs-keyword">typeof</span> MyComponent.created).toBe(<span class="hljs-string">'function'</span>)
})
<span class="hljs-comment">// 评估原始组件选项中的函数的结果</span>
it(<span class="hljs-string">'sets the correct default data'</span>, () =&gt; {
expect(<span class="hljs-keyword">typeof</span> MyComponent.data).toBe(<span class="hljs-string">'function'</span>)
<span class="hljs-keyword">const</span> defaultData = MyComponent.data()
expect(defaultData.message).toBe(<span class="hljs-string">'hello!'</span>)
})
<span class="hljs-comment">// 检查 mount 中的组件实例</span>
it(<span class="hljs-string">'correctly sets the message when created'</span>, () =&gt; {
<span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(MyComponent).$mount()
expect(vm.message).toBe(<span class="hljs-string">'bye!'</span>)
})
<span class="hljs-comment">// 创建一个实例并检查渲染输出</span>
it(<span class="hljs-string">'renders the correct message'</span>, () =&gt; {
<span class="hljs-keyword">const</span> Constructor = Vue.extend(MyComponent)
<span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Constructor().$mount()
expect(vm.$el.textContent).toBe(<span class="hljs-string">'bye!'</span>)
})
})</code></pre>
<h2 id="编写可被测试的组件"><a class="headerlink" href="#编写可被测试的组件" title="编写可被测试的组件"></a>编写可被测试的组件</h2><p>很多组件的渲染输出由它的 props 决定。事实上,如果一个组件的渲染输出完全取决于它的 props那么它会让测试变得简单就好像断言不同参数的纯函数的返回值。看下面这个例子</p>
<pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{{ msg }}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
<span class="hljs-attr">props</span>: [<span class="hljs-string">'msg'</span>]
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre>
<p>你可以在不同的 props 中,通过 <code>propsData</code> 选项断言它的渲染输出:</p>
<pre><code class="hljs js"><span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
<span class="hljs-keyword">import</span> MyComponent <span class="hljs-keyword">from</span> <span class="hljs-string">'./MyComponent.vue'</span>
<span class="hljs-comment">// 挂载元素并返回已渲染的文本的工具函数</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getRenderedText</span> (<span class="hljs-params">Component, propsData</span>) </span>{
<span class="hljs-keyword">const</span> Constructor = Vue.extend(Component)
<span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Constructor({ <span class="hljs-attr">propsData</span>: propsData }).$mount()
<span class="hljs-keyword">return</span> vm.$el.textContent
}
describe(<span class="hljs-string">'MyComponent'</span>, () =&gt; {
it(<span class="hljs-string">'renders correctly with different props'</span>, () =&gt; {
expect(getRenderedText(MyComponent, {
<span class="hljs-attr">msg</span>: <span class="hljs-string">'Hello'</span>
})).toBe(<span class="hljs-string">'Hello'</span>)
expect(getRenderedText(MyComponent, {
<span class="hljs-attr">msg</span>: <span class="hljs-string">'Bye'</span>
})).toBe(<span class="hljs-string">'Bye'</span>)
})
})</code></pre>
<h2 id="断言异步更新"><a class="headerlink" href="#断言异步更新" title="断言异步更新"></a>断言异步更新</h2><p>由于 Vue 进行 <a href="reactivity.html#异步更新队列">异步更新 DOM</a> 的情况,一些依赖 DOM 更新结果的断言必须在 <code>Vue.nextTick</code> 回调中进行:</p>
<pre><code class="hljs js"><span class="hljs-comment">// 在状态更新后检查生成的 HTML</span>
it(<span class="hljs-string">'updates the rendered message when vm.message updates'</span>, done =&gt; {
<span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(MyComponent).$mount()
vm.message = <span class="hljs-string">'foo'</span>
<span class="hljs-comment">// 在状态改变后和断言 DOM 更新前等待一刻</span>
Vue.nextTick(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
expect(vm.$el.textContent).toBe(<span class="hljs-string">'foo'</span>)
done()
})
})</code></pre>
<p>关于更深入的 Vue 单元测试的内容,请移步 <a href="https://vue-test-utils.vuejs.org/zh/" rel="noopener" target="_blank">Vue Test Utils</a> 以及我们关于 <a href="../cookbook/unit-testing-vue-components.html">Vue 组件的单元测试</a>的 cookbook 文章。</p>
<div class="guide-links">
<span><a href="single-file-components.html">单文件组件</a></span>
<span style="float: right;"><a href="typescript.html">TypeScript 支持</a></span>
</div>
<div class="footer">
<script src="//m.servedby-buysellads.com/monetization.js" type="text/javascript"></script>
<div class="bsa-cpc"></div>
<script>
(function(){
if(typeof _bsa !== 'undefined' && _bsa) {
_bsa.init('default', 'CKYD62QM', 'placement:vuejsorg', {
target: '.bsa-cpc',
align: 'horizontal',
disable_css: 'true'
});
}
})();
</script>
发现错误?想参与编辑?
<a href="https://github.com/vuejs/cn.vuejs.org/blob/master/srcunit-testing.md" target="_blank">
在 GitHub 上编辑此页!
</a>
</div>
</div>