Vue.jsのドキュメントには、カスタム入力コンポーネントの例があります。私はそのようなコンポーネントの単体テストをどのように書くことができるかを理解しようとしています。コンポーネントの使用法は次のようになります
<currency-input v-model="price"></currency-input>
完全な実装は https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events で見つけることができます
ドキュメントは言う
したがって、コンポーネントが
v-model
で動作するには、次のようにする必要があります(これらは2.2.0以降で構成できます)。
- 値の小道具を受け入れる
- 新しい値で入力イベントを発行する
v-model
で動作するようにこのコンポーネントを作成したことを確認する単体テストを作成するにはどうすればよいですか?理想的には、これらの2つの条件を具体的にテストするのではなく、コンポーネント内で値が変化するとモデルでも変化する動作をテストしたいと思います。
あなたはそれをすることができます:
<currency-input>
_<currency-input>
_の内部テキストフィールドに偽装します(_13.467
_は_<currency-input>
_から_12.46
_)price
プロパティ(_v-model
_にバインド)が変更された場合。サンプルコード(Mochaを使用):
_import { mount } from '@vue/test-utils'
import CurrencyInput from '@/components/CurrencyInput.vue'
describe('CurrencyInput.vue', () => {
it("changing the element's value, updates the v-model", () => {
var parent = mount({
data: { price: null },
template: '<div> <currency-input v-model="price"></currency-input> </div>',
components: { 'currency-input': CurrencyInput }
})
var currencyInputInnerTextField = parent.find('input');
currencyInputInnerTextField.element.value = 13.467;
currencyInputInnerTextField.trigger('input');
expect(parent.vm.price).toBe(13.46);
});
});
_
_var CurrencyInput = Vue.component('currency-input', {
template: '\
<span>\
$\
<input\
ref="input"\
v-bind:value="value"\
v-on:input="updateValue($event.target.value)">\
</span>\
',
props: ['value'],
methods: {
// Instead of updating the value directly, this
// method is used to format and place constraints
// on the input's value
updateValue: function(value) {
var formattedValue = value
// Remove whitespace on either side
.trim()
// Shorten to 2 decimal places
.slice(0, value.indexOf('.') === -1 ? value.length : value.indexOf('.') + 3)
// If the value was not already normalized,
// manually override it to conform
if (formattedValue !== value) {
this.$refs.input.value = formattedValue
}
// Emit the number value through the input event
this.$emit('input', Number(formattedValue))
}
}
});
// specs code ///////////////////////////////////////////////////////////
var mount = vueTestUtils.mount;
describe('CurrencyInput', () => {
it("changing the element's value, updates the v-model", () => {
var parent = mount({
data() { return { price: null } },
template: '<div> <currency-input v-model="price"></currency-input> </div>',
components: { 'currency-input': CurrencyInput }
});
var currencyInputInnerTextField = parent.find('input');
currencyInputInnerTextField.element.value = 13.467;
currencyInputInnerTextField.trigger('input');
expect(parent.vm.price).toBe(13.46);
});
});
// load jasmine htmlReporter
(function() {
var env = jasmine.getEnv()
env.addReporter(new jasmine.HtmlReporter())
env.execute()
}())
_
_<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css">
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/browser.js"></script>
<script src="https://rawgit.com/vuejs/vue-test-utils/2b078c68293a41d68a0a98393f497d0b0031f41a/dist/vue-test-utils.iife.js"></script>
_
注:上記のコードは(おわかりのように)正常に機能しますが、_v-model
_を含むテストはすぐに改善される可能性があります。最新情報については この問題 に従ってください。