Modifying properties within a Vue component instance for unit testing purposes

I am getting ready to test a specific behavior in a Vue component that only occurs when the props are changed. The Vue component I'm working with looks similar to this example, and the key logic for the test is contained within the watcher.

<script>
export default {
  components: {
  },
  props: {
    exampleProp: {
      type: Boolean,
      required: false,
      default: false,
    }
  },
  watch: {
    exampleProp: function(newVal, oldVal) {
        // Logic that needs testing
    },
  }
};
</script>

<template>
  <h1>hello world</h1>
</template>

When following the approach below, the test logic runs smoothly.

it('example test', done => {
    let wrapper = mount(exampleComponent, {
        propsData: {
        },
        template: `
        <example-component >
        </example-component>
    `
    });

    wrapper.setProps({
        isSubmitting: true
    });
});

The watcher is invoked and ready for testing, everything seems fine.

However, as the test is intended to be integrated into a test suite, there are some limitations. The component is not mounted directly, but rather the instance of it like so:

it('example test', done => {
     let wrapper = new Vue({
      components: {
        exampleComponent,
      },
      template: `
        <example-component></example-component>
      `,
    }).$mount();

    // How can I update the props now?
    // 'wrapper.setProps' and 'wrapper.$setProps' are both undefined
});

My goal is to find a way to update the props of the component instance in order to trigger the watcher's execution. Any suggestions on how to achieve this?

Answer №1

If you find it necessary to incorporate an actual Vue instance into the test-suite instead of utilizing the test-utils wrapper, there is a way to achieve this:

  1. Adjust the prop to depend on an arbitrary data property within the Vue instance itself (e.g., vm.unchanged).
  2. Add a vm.$set function inside the vm.mounted() lifecycle hook that modifies vm.unchanged, consequently activating the watch on exampleComponent.exampleProp.

const exampleComponent = {
  components: {
  },
  template: `<div>
<h1 style="color: green">ExamleProp unchanged: {{ exampleProp }}</h1>
<h1 style="color: red">Updated: {{ updated }}</h1>
</div>`,
  props: {
    exampleProp: {
      type: Boolean,
      required: false,
      default: false,
    }
  },
  data() {
    return {
      updated: false,
    };
  },
  watch: {
    exampleProp: function(newVal, oldVal) {
        this.updated = true;
    },
  }
};

const vm = new Vue({
      el: '#app',
      components: {
        exampleComponent,
      },
      data: {
        unchanged: true,
      },
      template: `
        <example-component :example-prop="unchanged"></example-component>
      `,
      mounted() {
        this.$set(this, 'unchanged', false);
      } 
    }).$mount();
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

Trust this information proves helpful!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adding to object properties in Typescript

My goal is to dynamically generate an object: newData = { column1: "", column2: "", column3: "", ... columnN: "" } The column names are derived from another array of objects called tableColumns, which acts as a global variable: table ...

Dealing with ASP.NET forms that involve a javascript plugin generating substitute input

I'm facing an issue with my ASP.NET MVC webpage where I submit a form using AJAX in the following way: function ValidateFormAndAjaxSubmit(formId, callingElement) { if (IsNotDblClick(callingElement.id)) { var _form = $("#" + formId); ...

Error message: "The property is not found within the specified type when using the OR operator with

Within my Angular component, I am faced with a challenge involving an Input that can be one of two types. @Input() profile: UserProfileDetails | BusinessProfileDetails; The structure of the profile template is straightforward and I want to avoid duplicati ...

Check if the input values are already in the array and if not, then add

Within my React application, I am displaying an Array and each entry in the Array is accompanied by an input element. These input elements are assigned a name based on the entry's ID, allowing users to enter values. To handle the changes in these inp ...

Adjust the height of a CSS div to automatically fit the space between two other divs

I am trying to adjust the height of my table (with class "body") so it automatically fits the remaining space between the header div and the footer div. All three divs are enclosed within a fixed and centered position on the screen. Update: JSFiddle w ...

Creating a fluid side navigation bar in reactjs

Can someone please help me with the following code issue? I am encountering an error related to the script tag when running it in ReactJS, although it works fine in a simple HTML file. Upon starting npm, an error is displayed pointing to line number which ...

JSON Schema: ensuring that all elements within an array are distinct and not null

I am currently in the process of developing a JSON schema that needs to meet the following criteria: The schema must declare a top-level object with at least one property Each property's value should be an array, with each array containing exactly N ...

When implementing jQuery for scrolling on a website, touch gestures may become unresponsive on Safari for iOS devices

While developing a custom website with Angular, I encountered an issue specifically with Safari on iOS. The website is a single-page app with multiple menu sections that trigger a scroll animation when selected using jQuery. Everything was working smoothly ...

Selecting multiple input elements in Jquery without relying on IDs

I am working with the following block of code: <div class="container"> <div class="row"> <div class="col"> <input class="form-control" type="text" id="#first"> </div> <div class="co ...

The GitHub-hosted package encounters a failure during the npm publish process

Last week everything was running smoothly, but now I am encountering an error and not sure what went wrong. (Apologies for the formatting as there are many lines of log) Running Node version: v10.15.3 Using npm version: 6.4.1 After executing npm publish ...

The addition of input fields on keyup creates problems in the initial field of each row

I am currently working with a table and attempting to calculate the sums as follows: td(1) + td(2) + td(3) = td(4), td(5) + td(6) + td(7) = td(8), td(9) + td(10) + td(11) = td(12). This is the code I have implemented: $(document).ready(function () { ...

What is Angular's approach to handling a dynamic and unprocessed JSON object?

When a JSON file is placed under assets, accessing it using something like http://localhost:4200/myapp.com/assets/hello.json will fetch the JSON file directly without any graphical user interface. This indicates that Angular must be able to return a raw JS ...

Enforce a restriction on the user's input value for the amount field within a React application

I'm looking to limit the user from entering more than 50000 in the input value. How can I achieve this using React? I am currently handling this on the onchange event. onPaymentAmountChanged = (e) => { let inputValue = e.target.value; if (i ...

How to stop cursor from changing on link click in Google Chrome

Have you ever noticed that when you click on a link in Chrome (but not Safari or Firefox), the cursor changes from pointer to arrow? Is there a way to prevent this behavior so that the pointer remains even after clicking, while still hovering over the link ...

Importing JS files or SDKs in Angular that are not modules

Currently, I am incorporating the Avaya SDK (which consists of 3 JS files) into my Angular project. However, when attempting to import it, I encounter an error stating that it is not recognized as a module. Any suggestions on how to resolve this issue? Th ...

I'm struggling to update a value in my view with Angularjs and Socket.io. It seems impossible to

In order to master AngularJS and NodeJS, I am embarking on creating a chatroom project. Everything seems to be functioning smoothly with Angular controllers and sending data to my NodeJS server using socket.io. However, I have encountered a problem: When m ...

What is the best way to dynamically adjust the height of an iframe based on its changing content

My webpage contains an iframe that loads content dynamically, and I want to center it on the page based on its height. The issue I'm facing is that while my code works well for increasing content heights, it fails to recognize when the content size de ...

Issues persist when using preventDefault() to prevent redirection

I'm having trouble figuring out what I'm doing wrong. The situation is as follows: I have a search function that uses jQuery to make an AJAX call to a PHP file for search results (preventDefault works here). Within the response, there's a bu ...

JS Unable to get scrollIntoView function to work with mousewheel event

I have been working with the script provided above. It correctly displays the id in the browser console, but unfortunately, it is not triggering the scrolling function as expected. var divID = null; var up = null; var down = null; function div(x) { s ...

Peruse the written content and implement it within a div element

If any of the words match, I want to highlight them in a different color on the website for the user to see. var main = document.getElementById("selectedItem").innerText; var opinionTargets = ["screen", "cover", "size", "waterproof", "voice", "light", "pr ...