Simulating User Input

Tram Ho

Activate Event

One of the most common things Vue components will do is to listen for user input. vue-test-utils and Jest make it easy to check the input. Let’s look at how to use trigger and Jest mocks to verify component components are working correctly.

The source code for the test described on this page can be found here .

Create component

We will create a simple component <FormSubmitter> , which contains a <input> and a <button> . When the button is clicked, something happens. The first example will only display a success message, then we’ll move on to a more interesting example like submitting the form to an external endpoint.

Create a <FormSubmitter> and enter the template template:

When the user submits the form, we will receive a message thanking them for submitting. We want to submit the form asynchronously, so we are using the @submit.prevent mechanism to prevent the default action, which is to refresh the page when the form is submitted.

Now add the submit form logic:

Quite simply, we only set the submitted true when the form was submitted, thus displaying the success message in the <div> tag.

Write a test

The test file is as follows:

We use the shallowMount component, naming the user using the trigger and vue-test-utils methods provide simulation of the user’s input. trigger works on custom events, and events using a modifier, as submit.prevent , keydown.enter

This test also follows the 3 steps of unit testing:

  1. sort (test setup. In our case, we render the component)
  2. action (perform actions on the system)
  3. assert (make sure the actual results match your expectations)

We separate each step with a new line because it makes the test more readable.

Run the test with yarn test:unit . Of course it will pass.

The trigger is very simple – use find to get the desired element to simulate some input and call the trigger with the name of the event and any modification tools.

Practical examples

Forms are usually submitted to certain endpoints. Let’s see if we can test this component with a different implementation than handleSubmit . A common practice is that the alias of the HTTP library is Vue.prototype.$http . This allows us to make an Ajax request by simply calling this.$http.get(...) . Find out more here .

Typically the HTTP library is axios, a common current HTTP client. In this case, we use handSubmit which might look like this:

In this case, a mock this.$http technique this.$http will create a desired test field. You can read about mocks described further [here]] ( https://vue-test-utils.vuejs.org/api/options.html#mocks ). Let’s mock an http.get method as follows:

There are a few interesting things going on here:

  • We create a variable url and data to save url and data transfer up to $http.get . This will be helpful to verify that the request is going to the correct endpoint with the correct payload.
  • After assigning the url and data arguments, we resolve the Promise. to successfully API feedback.

Before viewing the test file, here’s the new handleSubmitAsync function:

In addition, we also update the <template> to use the new handleSubmitAsync function:

Now, we just have to test.

Mocking an ajax call

First, include mock this.$http at the top, before the describe block:

Now, to add a test case, use $http with mocks as follows:

Instead of using any http library using Vue.prototype.$http , the mock implementation will be used instead. This we can control the environment of the test and get consistent results.

Running yarn test:unit will produce a fail test result:

The small problem is that our test is done before the promise before returning resolves mockHttp . We can solve it using async like this:

However, our test still ends before the promise resolves. One way to solve this problem is to use flush-promises , a simple Node.js module that will immediately resolve all pending promises . Install yarn add flush-promises , update the test changes as follows:

Now the test has passed. The source code for flush-promises about 10 lines of code, if you’re interested in Node.js it’s worth reading and understanding how it works.

We should also make sure the payload endpoint is correct. Add 2 assertes to our test file:

Our test still passes.

Conclude

In this section, we saw how to:

  • use trigger for events, even events that use modifiers like prevent
  • Use setValue to set the value of <input> using v-model
  • Write your tests in 3 unit tests
  • mock a method attached to Vue.protopyte along with using mocks to bind them
  • How to use flush-promises to solve the problem of resolving all flush-promises , a useful technique in unit testing

The source code for the source code is described here .

Share the news now

Source : Viblo