Vue Component Unit Testing - PullRequest
       30

Vue Component Unit Testing

0 голосов
/ 15 ноября 2018

У меня есть счетчик - довольно прямолинейный.

<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 голосов
/ 15 ноября 2018

Текстовые поля содержат текстовые значения. Обратите внимание, что вы даже указали текстовое значение: setValue('1'). Если вы измените значение на входе вручную (скажем, на 3) и нажмете кнопку увеличения, оно станет равным 31. Ваш тест говорит вам правду.

Вам нужно изменить свои функции для преобразования в число. [Обновить] Как ваш комментарий сообщил мне, Vue имеет модификатор .number для v-model для этой цели

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>
...