4

I am writing unit tests for some components I made at my job. We are using Mocha (TDD) and the Chai assertion library. I have a component with some checkboxes, and using the setChecked() method on them from vue-test-utils is not behaving as expected. I have made a small example that reproduces the error:

TestComponent.vue:

<template>
    <div>
        <input class="checkboxTest" type="checkbox" v-model="cbVal">
        <input class="inputTest" type="text" v-model="textVal">
    </div>
</template>

<script>
    define([], function() {
        return {
            data: function() {
                return {
                    cbVal: false,
                    textVal: ""
                }
            }
        }
    })
</script>

test.js:

suite("Random test", function() {
  var VueTest;
  var TestComponent;

  //Import the vue test utils library and TestComponent
  suiteSetup(function(done) {
    requirejs(
      ["vue-test-utils", "vuec!components/TestComponent"],
      function(VT, TC) {
        VueTest = VT;
        TestComponent = TC;
        done();
      }
    );
  });


  //This test passes
  test("fill in the input", function() {
    var wrapper = VueTest.mount(TestComponent);
    wrapper.find(".inputTest").setValue("Hello, world!");

    assert.equal(wrapper.vm.textVal, "Hello, world!");
  });

  //This one does not
  test("programatically check the box", function() {
    var wrapper = VueTest.mount(TestComponent);
    wrapper.find(".checkboxTest").setChecked(true);

    //Prints out AssertionError: expected false to equal true
    assert.equal(wrapper.vm.cbVal, true);
  });
});

The textVal data member in TestComponent is getting changed, but cbVal is not. Can anyone please explain why setValue() works just fine, but setChecked() does not? Thank you in advance.

1
  • 1
    This looks like a bug, setChecked is intended to update the element and the Vue model. Can you please create a minimal reproduction and create an issue for Vue Test Utils? Commented Nov 23, 2018 at 17:36

2 Answers 2

4

I had a similar issue and the accepted answer did not solve my problem. I don't think the accepted answer is correct either, as setChecked was added specifically to avoid having to manually set the values via the elements.

In my case, I wanted Vue to react to the v-model change and redraw. I tried async and many other methods, until finding the one that works: wrapper.vm.$forceUpdate().

Here's what my working code looks like:

wrapper.find("#someRadioButtonId").setChecked(true)
// manually force Vue to update
wrapper.vm.$forceUpdate() 
expect(wrapper.find("#someRadioButtonId").classes()).toContain("selected") // success!
Sign up to request clarification or add additional context in comments.

Comments

-1

I can't answer why it doesn't work, but I can tell you your approach is incorrect in the first place.

You shouldn't be interacting with the html elements directly to set their values. When you set vue-model to cbVal you should instead be interacting with cbVal.

In other words, change your code from setChecked() to cbVal = true in order for it to comply with how Vue wants you to develop your project. There's no guarantee Vue can remain dynamic and reactive if you don't interact with your code the way Vue wants you to.

2 Comments

Yeah, I realized that what I had to do was something like var cb=wrapper.find(".checkboxTest"), then cb.trigger("click"). This changed the variable in v-model. Still not sure what setChecked() is doing internally.
This answer doesn't make sense at all. The vue team actually encourages to test input and output and treat the component itself as a black box. So setting the checkbox value to true with setChecked is actually the right way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.