Giter Club home page Giter Club logo

Comments (13)

alexjoverm avatar alexjoverm commented on September 26, 2024 45

I've found out an easier way:

it('is required, is a String and validates correctly', () => {
  cmp = createCmp()
  const message = cmp.vm.$options.props.message
  
  expect(message.required).toBeTruthy()
  expect(message.type).toBe(String)
  expect(message.validator && message.validator('a')).toBeFalsy()
  expect(message.validator && message.validator('aa')).toBeTruthy()
})

At least here is not necessary to use spies, and it works, independently on how you define the props, either in the shorthand way message: String or as an object, since Vue expands them.

Anyway, it would be cleaner if vue-test-utils have a way to access some stuff on the Wrapper:

  • getProps()
  • getAttributes()
  • getOptions()
  • ... others?

The first 2 (in singular) are tracked in #27, but not getOptions() which would be an abstraction to not enter the full internal path .vm.$options.props.message.

What do you think @LinusBorg @wparad?

from vue-test-utils.

HunorMarton avatar HunorMarton commented on September 26, 2024 15

If you define your components simply as an object:

export default {
  name: 'Component',
  props: {
    message: {
      type: String,
      required: true,
      validator: function(value) {
        return value == 'Hello'
      }
    } 
  }
}

Then you save yourself a lot of trouble:

  test('props validator', () => {
    const message = Component.props.message

    expect(message.validator).toBeInstanceOf(Function)
    expect(message.validator('Hello')).toBeTruthy()
    expect(message.validator('Hi')).toBeFalsy()
  })

from vue-test-utils.

alexjoverm avatar alexjoverm commented on September 26, 2024 2

Well I'd agree if that would work in that way... but how's currently working you cannot test that, since even if the value is invalid, it still passes. Let me explain. Given a Message component with a message property as:

props: {
     message: {
        type: String,
        required: true
      }
}

I'd expect the following test to fail, but it doesn't:

     it('message is of type string', () => {
        cmp = createCmp({ message: 42 })
        expect(cmp.hasProp('message',42)).toBe(true)
        expect(cmp.vm.message).toBe(42)
      })

And of course, if you pass no message, it will be undefined, which doesn't test anything.

I'd like to test that a property of a component indeed is required and validates properly. Right now the cleaner it got is like this:

      let spy = jest.spyOn(console, 'error')
      afterEach(() => spy.mockReset())


      it('message is of type string', () => {
        cmp = createCmp({ message: 1 })
        expect(spy).toBeCalledWith(expect.stringContaining('[Vue warn]: Invalid prop'))
      })

      it('message is required', () => {
        cmp = createCmp()
        expect(spy).toBeCalledWith(expect.stringContaining('[Vue warn]: Missing required prop'))
      })


      it('message has at least length 2', () => {
        cmp = createCmp({ message: 'a' })
        expect(spy).toBeCalledWith(expect.stringContaining('[Vue warn]: Invalid prop'))
      })
      
      it('message is OK when called with expected props', () => {
        cmp = createCmp({ message: 'hey' })
        expect(spy).not.toBeCalled()
      })

from vue-test-utils.

GreggOD avatar GreggOD commented on September 26, 2024 2

Any ideas how to do this on a functional component seeing as jest doesn't allow you to access props of a functional?

Using Vue CLI 3.

from vue-test-utils.

eddyerburgh avatar eddyerburgh commented on September 26, 2024 1

The test you posted in your original post is fine. It tests what you want it to test.

I don't think we should add a method to help test props validation.

from vue-test-utils.

alexjoverm avatar alexjoverm commented on September 26, 2024 1

@eddyerburgh that's true, although I find easier an cleaner to do it as #34 (comment), since there is no need to spy on globals, or assert in side effects like the console. Do you agree on that? An example could be added to docs as per #18 maybe :)

A side question I was thinking is, if it would be useful to have a getOptions function, just to avoid the vm.$options.props.message call. You know, probably in a major Vue version those internal props change, so it could be an abstraction over. What do you think?

from vue-test-utils.

wparad avatar wparad commented on September 26, 2024

That would mean unit testing that Vue is working, which should be out of scope of any test. Instead you are probably interested not in the fact that validation rule works correctly, but that the validation is configured correctly. That should be easier to ensure.

from vue-test-utils.

LinusBorg avatar LinusBorg commented on September 26, 2024

Agree with wparad. you should pass a couple of valid and invalid values to components and verify that the value either passes or doesn't, by checking if the prop's value on the component is undefined.

from vue-test-utils.

wparad avatar wparad commented on September 26, 2024

@alexjoverm, I do like. As mentioned above, I like that you are testing the configuration of the validator, so you get a thumbs up from me 👍

from vue-test-utils.

eddyerburgh avatar eddyerburgh commented on September 26, 2024

I think there is a case for adding a getOptions method, and would be interested in hearing other opinions. Could you create an issue for it @alexjoverm?

from vue-test-utils.

alexjoverm avatar alexjoverm commented on September 26, 2024

Done ;)

from vue-test-utils.

carlos-contreras avatar carlos-contreras commented on September 26, 2024

This worked for us:

/*
* Ref: https://jestjs.io/docs/en/expect.html#custom-matchers-api
* this file is required on app/javascript/test/unit/jest.conf.js
*/

const customMatchers = {
  toTriggerError(received) {
    const spy = spyOn(console, "error")

    received()

    const pass = !!spy.calls.mostRecent() && spy.calls.mostRecent().args[0].includes("[Vue warn]:")

    return {
      message() {
        return `expected ${received} to trigger error`
      },
      pass,
    }
  },
}

expect.extend(customMatchers)

from vue-test-utils.

Ge6ben avatar Ge6ben commented on September 26, 2024

I've found out an easier way:

it('is required, is a String and validates correctly', () => {
  cmp = createCmp()
  const message = cmp.vm.$options.props.message
  
  expect(message.required).toBeTruthy()
  expect(message.type).toBe(String)
  expect(message.validator && message.validator('a')).toBeFalsy()
  expect(message.validator && message.validator('aa')).toBeTruthy()
})

At least here is not necessary to use spies, and it works, independently on how you define the props, either in the shorthand way message: String or as an object, since Vue expands them.

Anyway, it would be cleaner if vue-test-utils have a way to access some stuff on the Wrapper:

  • getProps()
  • getAttributes()
  • getOptions()
  • ... others?

The first 2 (in singular) are tracked in #27, but not getOptions() which would be an abstraction to not enter the full internal path .vm.$options.props.message.

What do you think @LinusBorg @wparad?

Hi thanks but why it need @ts-ignore to work with typescript ?!

from vue-test-utils.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.