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

Error in tests with slots in Mocha #1166

Closed
victorborrasdev opened this issue Dec 21, 2021 · 16 comments
Closed

Error in tests with slots in Mocha #1166

victorborrasdev opened this issue Dec 21, 2021 · 16 comments
Labels
bug Something isn't working

Comments

@victorborrasdev
Copy link

Hi! I think this is more of a question than a Vue Test Utils issue really, but I was hoping any of you could give me any pointer to what to look for.

We use Karma + Mocha, and we're seeing that tests that contain slots throw the following error: TypeError: Cannot convert undefined or null to object.

I have created a reproduction with both Mocha and Jest (see below) and this only happens with the former, and Jest works perfectly, that's why I'm thinking it's not VTU's fault.

The only difference I've noticed is that Mocha tests use vue-test-utils-esm-bundler.js and Jest uses vue-test-utils.cjs.js. Maybe the problem is there?

I have tried using a function as suggested by @lmiller1990 here, but the problem with this approach is that if we pass HTML, it will be rendered as text. For instance, when passing () => '<strong>Hello</strong>' the result of wrapper.html() will be &lt;strong&gt;Hello&lt;/strong&gt;. This might be acceptable for many use cases, but maybe this is an unexpected behavior that needs to be addressed?

Reproduction

This is a Vue CLI project in which I've chosen Mocha+Chai as the testing option, and then I've added Jest.

https://github.com/victorborrasdev/vue-test-utils-mocha-slots

Run Jest tests. They should pass:

npm run test:jest

Run Mocha tests. They should throw the error:

npm run test:jest
@lmiller1990
Copy link
Member

Someone looked into this and DM'd me recently, dumping the DM log here for reference when I (or someone) fixes this:


  • Tracked this down in VTU in a place where it trys to run a function that is compiled from Vue: https://github.com/vuejs/vue-test-utils-next/blob/b45ff43d1433e581a5d37c332474b2d7f64a5420/src/utils/compileSlots.ts#L31
  • Vue seems to return different code from the compile function based on environment. I think if BROWSER is false, it returns code that uses the with (_ctx) syntax that throws the error. For some reason the Cypress CT tests are loading the vue-test-utils.esm.bundler.js , which is rollup outputs if __BROWSER is false.
  • When tests are run with Jest, the code returned from compile doesn’t have the with (_ctx) surrounding the code block, and BROWSER is set to true in config

Something to do with our build step.

@lmiller1990 lmiller1990 added the bug Something isn't working label Dec 21, 2021
@lmiller1990
Copy link
Member

I am having trouble figuring this out, I cannot reproduce it outside of the repo you provided (eg in here). It's tough to get a truly minimal reproduction.

A work-around that would likely work is something like

import { h } from 'vue'

slots: {
  default: () => h('strong', 'my content')
}

I'll keep working on this problem, but that might help in the meantime.

@victorborrasdev
Copy link
Author

victorborrasdev commented Dec 22, 2021

It was failing for me with a plain Vue CLI project, with Mocha + Chai selected as the unit testing option, and a component with a slot. If by truly minimal you mean just Vue + VTU + Mocha + Webpack (no Vue CLI), just let me know and I'll try to put it together.

A work-around that would likely work is something like

Yes, that and the function with a string should work in many cases, so thanks for that!

I guess this isn't really a big deal since you usually want to test that the component loads some slot content and the plain string should do. You could even argue that wanting to test that HTML is rendered correctly is like testing Vue slots themselves and totally unnecessary. It's just a bit of a "weird" behavior and I wanted to bring it up just in case you thought it's worth adjusting :)

@lmiller1990
Copy link
Member

lmiller1990 commented Jan 6, 2022

I could not find out what the problem is - I think it's related to our rollup config and how we bundle things, but I don't have any idea how to proceed right now. We will need to do a bit more of a deep dive to figure out what's going on. Let me know if you come up with anything in the meantime.

I could reproduce with a Vue CLI project - I was hoping to reproduce it in here, but even with a webpack config and mocha, I could not.

@victorborrasdev
Copy link
Author

We've paused the Vue 3 migration for now, but I'll take a look at this as soon as I'm back to it. Should we close the issue and reopen it if I make any advance, so you don't have it pending meanwhile?

@lmiller1990
Copy link
Member

If it's still a problem, we should leave it open 👍 so other people know, and perhaps someone has a fix.

@hjri
Copy link

hjri commented Mar 22, 2022

thanks for the workaround, been banging my head almost the entire day on this

@braddialpad
Copy link
Contributor

We just migrated to Vue 3 and are also having this issue. Don't really want to rewrite every single one of our tests to a render function and seems like the render function is unable to handle HTML. This seems like a bug in test-utils, is there any solution?

@lmiller1990
Copy link
Member

I don't know how to solve this one right now. It might be as simple as telling webpack to use cjs build instead of the esm build.

I dug into the problem a little more (see above) but it seems like a conflict of various build tools, as opposed to a true bug in Test Utils. Can you share the kind of tests you are writing? I wonder if we can find an alternative, more simple way to fix this, or at least unblock people for their migration.

@hjri
Copy link

hjri commented Mar 25, 2022

for me workaround was to use h('tag', ...) instead of string template in a .js file, for jsx you might wanna use jsx instead

@braddialpad
Copy link
Contributor

My team did a bit more research and we found that this started happening v.2.0.0-rc.13. If we downgrade to v.2.0.0-rc.12 string slots work fine.

Seems that it may have been caused by this PR #815

We are using Mocha/Chai/Sinon with vue-cli (@vue/cli-plugin-unit-mocha)

@lmiller1990
Copy link
Member

Thanks for the research @braddialpad - seems like we know how to potentially fix it (un-revert that change, or adapt it to work with the latest RC). Would you or someone in your team be interested in making a PR?

@braddialpad
Copy link
Contributor

I will give it a shot

@lmiller1990
Copy link
Member

I am hitting this in Cypress https://app.circleci.com/pipelines/github/cypress-io/cypress/35454/workflows/a6925305-5a8d-4638-988f-5d37fd502881/jobs/1412531?invite=true#step-112-856 (several layers of abstraction on top of Test Utils).

Good news... if this is a blocker in my day job, I will be able to spend more resources fixing it 😎

@braddialpad
Copy link
Contributor

Finally got some time to dig into this a bit, think I found a fix, PR is up!

@freakzlike
Copy link
Collaborator

Successfully tested after fixes from #1462
Good job @braddialpad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants