Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing of computed properties #15

Closed
ryanjgill opened this issue Mar 20, 2017 · 14 comments
Closed

Testing of computed properties #15

ryanjgill opened this issue Mar 20, 2017 · 14 comments
Assignees

Comments

@ryanjgill
Copy link

When trying to test a computed property using AVA and with Avoriaz, the context of this is not what is expected. I'm trying to use a computed property that is based on some data from the component.

More details on stackoverflow.

@eddyerburgh eddyerburgh self-assigned this Mar 20, 2017
@eddyerburgh
Copy link
Owner

eddyerburgh commented Mar 21, 2017

Three potential solutions here:

  1. Deprecate computed, propsData and methods methods, since they return methods that are not bound to the vue instance. Encourage use of wrapper.vm for testing methods and data instead:
const wrapper = mount(Component, {computed: { someMethod }})
expect(wrapper.vm.someMethod).to.equal(someMethod) // true :)
  1. Bind all methods returned from computed(), methods() and propsData() to the vm instance. This would cause strange behavior:
function someMethod(){
  console.log(this)
}
const wrapper = mount(Component, {computed: { someMethod }})
expect(Component.computed().someMethod).to.equal(someMethod) // throws assertion error
  1. Most radical - remove computed, methods and propsData methods and change the root of the wrapper to be the vue instance with added avoriaz methods. The vue instance(vm) already supports easy checking of methods and data:
const wrapper = mount(Component, {computed: { someMethod }})
expect(wrapper.someMethod).to.equal(someMethod) // true

Problems with this:

  1. avoriaz methods could clash with component data or methods (ie. a component with a find method will clash with the avoriaz find method)
  2. It's not really a wrapper anymore

So far I'm leaning towards the first solution

I'd really appreciate any suggestions from others.

I think the best thing to do right not is log an error when method(), computed() and propsData() are called.

@eddyerburgh
Copy link
Owner

@atilacamurca @stephane thoughts on the above?

@atilacamurca
Copy link
Contributor

I agree with you, you should always keep it a wrapper.

@eddyerburgh
Copy link
Owner

@ryanjgill I can't think of a good way of fixing this. Instead I've added a warning that points to this issue and suggest using wrapper.vm.methodName to access computed functions that use this.

@ryanjgill
Copy link
Author

@eddyerburgh Sounds good. Thanks for all the feedback guys!

@jasperck
Copy link

jasperck commented Mar 30, 2017

hi @eddyerburgh
I was writing tests for my vue component,
when I tried to test the part of props, I was doing something like this

given(
  ...some test data
)
  .it('should accept prop:', (propName, propValue) => {
    const wrapper = mount(InfiniteScroller, {
      propsData: { propName: propValue }
    });
    expect(wrapper.propsData().propName).to.equal(propValue);
  });

Then I got this warning messages and found out the reason in the issue from the messages.

WARN: 'warning: functions returned by propsData() will not have this bound to the vue instance. Calling a propsData function that uses this will result in an error. You can access propsData functions by using the vue instance. e.g. to call a method function named propsDataFunc, call wrapper.vm.propsDataFunc(). See https://github.com/eddyerburgh/avoriaz/issues/15'

According to the comment #15 (comment), looks like there is still no solution for somethink like

expect(wrapper.vm.propName).to.equal(propValue);

am I right, guys?

@eddyerburgh
Copy link
Owner

@jasperck Both of your examples should work. The warning message is only meant for users trying to call propsData that use this.

@jasperck
Copy link

@eddyerburgh Thanks, I see, but actually it only worked for

expect(wrapper.propsData().propName).to.equal(propValue);

but not

expect(wrapper.vm.propName).to.equal(propValue);

// test output
expected undefined to equal `propValue`

calling prop directly on vm just caused some error about getting undefined

@eddyerburgh
Copy link
Owner

eddyerburgh commented Mar 30, 2017

@jasperck Hi, sorry for the miselading message. I've updated and released a correct warning message in 1.9.4.

To access props with this bound the vue instance, you must run:

expect(wrapper.vm.$props.propName).to.equal(propValue);

@beliolfa
Copy link
Contributor

Hi.

I am trying to follow the steps in the warning in order to check a computed but I get an error
TypeError: wrapper.vm.welcomeText is not a function

and this is the code

t.is(wrapper.vm.welcomeText(), 'INTRODUCTION TEXT HERE');

Of course, the computed exists in the component.

@eddyerburgh
Copy link
Owner

eddyerburgh commented Jun 21, 2017

@disitec computed methods are used as getter functions for the property - https://vuejs.org/v2/guide/computed.html#Computed-Properties

t.is(wrapper.vm.welcomeText, 'INTRODUCTION TEXT HERE');

Should pass

@beliolfa
Copy link
Contributor

Yep, It works.

So, I think you shuould update the warning without parenthesis ;)

Thanks!

@eddyerburgh
Copy link
Owner

Fancy making a PR? 😉

@beliolfa
Copy link
Contributor

Here you have.

#63

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants