Vue组件单元测试



我有一个计数器组件-非常直接。

<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:
});

我无法让这个单元测试工作!如有任何帮助,我们将不胜感激!

文本字段包含文本值。请注意,您甚至指定了一个文本值: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>

相关内容

  • 没有找到相关文章

最新更新