Vue组件单元测试

时间:2018-11-15 01:05:19

标签: unit-testing vue.js vuejs2 jestjs vue-component

我有一个计数器组件-非常简单。

<div> + </div>
    <input type="text" v-model="countData" />
<div> - </div>

详细代码在这里-https://github.com/Shreerang/Vue-Nuggets/blob/master/src/components/QuantitySelector/QuantitySelector.vue

我正在尝试对该组件进行单元测试。

it('Renders a default quantity selector with the max count set to 6', () => {
    const wrapper = shallowMount(QuantitySelector);
    wrapper.find('input[type="text"]').setValue('1');
    expect(wrapper.find('input[type="text"]').element.value).toBe('1'); // notice here that the value is a String, whereas I expect it to be a Number

    wrapper.findAll('div').at(2).trigger('click');
    expect(wrapper.vm.countData).toBe('2'); // This fails as countData becomes "11" instead of doing a 1 + 1 = 2 and then becoming Number 2.

    expect(wrapper.find('input[type="text"]').element.value).toBe(2); // You can notice the same thing as above.

    wrapper.find('input[type="text"]').setValue(wrapper.vm.countData); // Do I have to do this? This does not seem right to me :frowning:
});

我无法进行此单元测试!感谢您提供任何帮助!

1 个答案:

答案 0 :(得分:0)

文本字段包含文本值。请注意,您甚至指定了一个文本值:setValue('1')。如果您手动更改输入中的值(例如更改为3),然后按增量按钮,则它变为31。您的测试正在告诉您真相。

您需要更改功能才能转换为数字。 [更新]正如您的评论所知,Vue为此专门为v-model设置了.number修饰符

new Vue({
  el: '#app',
	name: 'quantity-selector',
	props: {
		count: {
			type: Number,
			default: 1,
		}, // Makes sense to have default product count value
		maxCount: {
			type: Number,
			default: 6,
		}, // maxCount makes sense when you have a restriction on the max quantity for a product
		iconDimensions: {
			type: Number,
			default: 15,
		},
		minusIconFillColor: {
			type: String,
			default: '#000',
		},
		plusIconFillColor: {
			type: String,
			default: '#000',
		},
		isCountEditable: {
			type: Boolean,
			default: true,
		},
	},
	data() {
		return {
			countData: this.count,
		};
	},
	computed: {
		minusIconColor: function() {
			return this.countData === this.count ? '#CCC' : this.minusIconFillColor;
		},
		plusIconColor: function() {
			return this.countData === this.maxCount ? '#CCC' : this.plusIconFillColor;
		},
	},
	methods: {
		decrement: function() {
			if (this.countData > this.count) {
				this.countData -= 1;
			}
		},
		increment: function() {
			if (this.countData < this.maxCount) {
				this.countData += 1;
			}
		},
		adjustCount: function() {
			if (this.countData > this.maxCount) {
				this.countData = this.maxCount;
			} else if (this.countData < this.count) {
				this.countData = this.count;
			} else {
				if (isNaN(Number(this.countData))) {
					this.countData = this.count;
				}
			}
		},
	}
});
.nugget-quantity-counter {
	display: inline-flex;
}
.nugget-quantity-counter div:first-child {
	border: solid 1px #ccc;
	border-radius: 5px 0px 0px 5px;
}
.nugget-quantity-counter div:nth-child(2) {
	border-top: solid 1px #ccc;
	border-bottom: solid 1px #ccc;
	display: flex;
	flex-direction: column;
	justify-content: center;
}
.nugget-quantity-counter input[type='text'] {
	border-top: solid 1px #ccc;
	border-bottom: solid 1px #ccc;
	border-left: none;
	border-right: none;
	text-align: center;
	width: 20px;
	padding: 12px;
	margin: 0;
	font-size: 16px;
}
.nugget-quantity-counter div:last-child {
	border: solid 1px #ccc;
	border-radius: 0px 5px 5px 0px;
}
.nugget-quantity-counter > div {
	cursor: pointer;
	padding: 12px;
	width: 20px;
	text-align: center;
}
.nugget-quantity-counter > div > svg {
	height: 100%;
}
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <div @click="decrement">
    <svg viewBox="0 0 24 24" :width="iconDimensions" :height="iconDimensions">
                <g>
                    <path d='M64 0 M2 11 L2 13 L22 13 L22 11 Z' :fill="minusIconColor" />
                </g>
            </svg>
  </div>
  <input v-if="isCountEditable" type="text" v-model.number="countData" @blur="adjustCount" />
  <div v-else>{{countData}}</div>
  <div @click="increment">
    <svg viewBox="0 0 24 24" :width="iconDimensions" :height="iconDimensions">
                <g>
                    <path d="M 11 2 L 11 11 L 2 11 L 2 13 L 11 13 L 11 22 L 13 22 L 13 13 L 22 13 L 22 11 L 13 11 L 13 2 Z" :fill="plusIconColor" />
                </g>
            </svg>
  </div>
</div>