Vue-test-utils: Add a getProp and getAttribute methods

Created on 10 Aug 2017  路  4Comments  路  Source: vuejs/vue-test-utils

Currently we have a hasAttribute, hasProp and hasStyle methods. These aren't great for assertions, as they return booleans. If tests fail, they will fail because they were expecting true but received false.

For example, when asserting attributes with hasAttribute:

expect(wrapper.hasAttribute('attribute', 'value')).toBe(true) // expected false to be true

An alternative would be to have a getAttribute function:

expect(wrapper.getAttribute('attribute')).toEqual('value') // expected 'wrong value' to equal 'value'

This makes debugging a lot easier, and provides a better testing experience.

I think we should add get methods for props and attributes. We could do the same with style, but this won't be ideal - because the styles we return will be the computed styles:

expect(wrapper.getStyle('background')).toEqual('red') // expected 'rgb(250, 251, 252) none repeat scroll 0% 0% / auto padding-box border-box' to equal 'red'

I think we should keep hasAttribute, hasProp and hasStyle, but add getAttribute and getProp

Most helpful comment

Happened across this issue since you are asking for input on it, so here's my input:

This API makes sense to me. At first I wondered why we don't just use .attribute() instead of .getAttribute(), but it is more explicit what the method does when it lives alongside .hasAttribute().

Where things start to get dicey (in my opinion) is when we stop looking at attributes and start looking at Vue instance properties such as props, data object properties, computed properties, methods, injected dependencies, etc. All of these things are accessed homogeneously and it's up to the developer to have an understanding of what each one is.

What that means to your proposed API is that we have to start considering if props are different from those other Vue instance properties. Do we create methods for each type? Or do we embrace Vue's harmonized instance member access somehow with a differently named API? Attributes are sufficiently different from props to warrant different treatment.

Option 1: .hasAttribute() .getAttribute() .hasProp() .getProp() .getData() .hasData()

Option 2: .hasAttribute() .getAttribute() .has() .get()

Maybe the type or location of the instance member is worth testing. Someone might want to ensure that a provided service is available on a descendant component using .getInject(), or that something is known as a data object property as opposed to a prop, for instance. Or, maybe they don't care.

It's a tough API to nail down.

All 4 comments

Happened across this issue since you are asking for input on it, so here's my input:

This API makes sense to me. At first I wondered why we don't just use .attribute() instead of .getAttribute(), but it is more explicit what the method does when it lives alongside .hasAttribute().

Where things start to get dicey (in my opinion) is when we stop looking at attributes and start looking at Vue instance properties such as props, data object properties, computed properties, methods, injected dependencies, etc. All of these things are accessed homogeneously and it's up to the developer to have an understanding of what each one is.

What that means to your proposed API is that we have to start considering if props are different from those other Vue instance properties. Do we create methods for each type? Or do we embrace Vue's harmonized instance member access somehow with a differently named API? Attributes are sufficiently different from props to warrant different treatment.

Option 1: .hasAttribute() .getAttribute() .hasProp() .getProp() .getData() .hasData()

Option 2: .hasAttribute() .getAttribute() .has() .get()

Maybe the type or location of the instance member is worth testing. Someone might want to ensure that a provided service is available on a descendant component using .getInject(), or that something is known as a data object property as opposed to a prop, for instance. Or, maybe they don't care.

It's a tough API to nail down.

Hi, @daekano.
Though Vue forces us to make each member name unique among all props & data, it's still good to be explicit to tell what we are going to test.

So on reflection, getProps or get is not a good idea. It will return an unbound value, so if the prop/ method/ data/ whatever is a function that references this it won't behave as expected.

I'm going to close this for the moment. We should encourage users to use getAttribute on the Wrapper element:

wrapper.element.getAttribute('attribute')

And for props/data:

wrapper.vm.propName
Was this page helpful?
0 / 5 - 0 ratings