Vue Testing Library: How to mock Vue component - javascript

I used React Testing-Library, but not Vue Testing-Library before https://testing-library.com/docs/vue-testing-library/intro/ and I don't want to use mount or shallowMount where I can provide a stub. I want to figure out how to do that in VTL.
We usualy have components that use other components. So when testing our component say ComponentA it may use ComponentB and ComponentC. While there are some components that we want to be rendered (ComponentA and ComponentB) and want to test how they interact with our component, there are also others (ComponentC), which we may not want to test here, because they have their own tests. I.e. we want to "shallow-render" ComponentC when testing ComponentA.
Using react testing library we can do this:
import * as mockedComponentCModule from '....ComponentC';
jest.spyOn(mockedComponentCModule, 'ComponentC').mockImplementation(() => (
<div data-testid="mocked-component-c" />
));
or I like this
jest.mock('path/to/my/ComponentC', () => ({
ComponentC: function ComponentC() {
return <div data-testid="mocked-component-c" />;
}
}));
So in react when we do render(<ComponentA />) the ComponentC will render as a simple div instead of the actual component.
My question is - how can I do this with Vue Testing Library?

I think I figured it out:
jest.spyOn(mockedComponentCModule.default, 'render').mockImplementation((create) =>
create('div', { attrs: { 'data-testid': 'mocked-component-c' } }, 'Test Content')
);
Now sure if there's a better way - I'd be thankful if someone points me in the right direction

Related

Convert website from HTML,CSS,bootstrap & JQuery to React?

Hi guys hope you're fine, I'm student and I have this year to do some thing like a project to end my studies , so I chose to create a website (using React/Django) I already have the site but made by HTML,CSS,bootstrap & JQuery , so now i have to convert it to react , but i have a problem i don't know how to include some js files inside a components , every things else is going good, I need just what is in the js files to applied it in some components.
Hope you help me out.
cordially
You can have javascript code inside your components likewise
const Component = props => {
//javascript code
return (<div>-- Component JSX---</div>)
}
if the javascript code if just needed for the initializing of the component you can use react hooks to run a piece of code only one time after the component is created.
import React, { useEffect } from 'react';
const Component = props => {
useEffect(() => {
// javascript code
}, [])
return (<div>--Component JSX---</div>
}
the empty array as second argument indicates the useEffect hook that the effect should only be ran once after the component has been initialized.
So the way React works is you will be building "HTML" using React functional/class components like this example
import React from 'react';
//Just like a normal javascript function, it listens to in this
instance, the return statement. You're returning regular HTML.
function Navbar() {
return (
<div>This is some text built by react</div>
<p>Saying hello to react by building a functional component</p>
)
}
export default Navbar; //This right here is exporting the file so it can be
//used elsewhere just import it in other file.
So the return is where you will build your website, then in the next component you will import should look something like this.
Normally, it is called App.js or in some instances where it's more complex it's anythinng you want.
import Navbar from '../components/Navbar.js';
function App() {
return (
<Navbar /> //Now you don't have to write your main content in here you can
//just import it. Just like Navbar
<div>This is my main content in page</div>
)
}

How to use React.lazy for a component of a module?

I am using the npm package called '#toast-ui/react-editor'. It includes a 'Viewer' react component. I could just use:
const Viewer = require("#toast-ui/react-editor").Viewer
But it increases the bundle size a lot. So I wanted to load it lazily whenever it is needed by using React.lazy. I am going to use it inside component:
<Viewer {...props} />
But I don't have any clue how to do it.
I tried this way, but didn't work.
const Lazy = React.lazy(() => import(require("#toast-ui/react-editor"))).Viewer;
I really want to know how to do it.
As Viewer is not a default component, it's not as simple as removing require, (which is not even needed, though).
You need to import it dynamically and then return the module as a default one (as that's what lazy expects and works with only).
const Viewer = lazy(() =>
import("#toast-ui/react-editor").then(module => {
return { default: module.Viewer };
})
);

Why HOC are applied during exporting of component in place of importing it

My basic understading is that HOC like connect (for connecting with redux store) and other HOC's are applied to a component while exporting it.
Like this
import React, { Component } from 'react';
import './App.css';
import myHoc from './myHoc/index';
class App extends Component {
render() {
return (
<div className="App">
</div>);
}
}
export default myHoc({})(App);
Where as a better thing would be to apply HOC during import as it would make it easier to make reusable component. The same component can pick up props from store or from props and that would be the responsibility of the parent component to check what to give which HOC to apply on the component.
I know we can use container components which takes the component and render children but that just adds code in the JSX (wont look good if there are many container components)
though we can do it like this
import React, { Component } from 'react';
import './App.css';
import myHoc from './myHoc/index';
import AppChild from './AppChild';
const NewAppChild = myHoc({}, ()=> {
})(AppChild);
class App extends Component {
state = {
count: 1,
};
reRender = () => {
this.setState({count: this.state.count + 1});
};
render() {
return (
<div className="App">
<NewAppChild handleClick={this.reRender} count={this.state.count}/>
</div>
);
}
}
export default App;
What my question is that, is there something better that can handle this kind of situations where I want to apply my HOC on import that is each many container components can import it and they can apply different HOCs depending on the needs.
There is no single concrete reason for this design choice - as you have already seen you can invoke your HOC wherever you use the component - but I see at least 1 advantage: configuration & component reuse.
In your example, myHoc takes no parameters or configuration so this doesn't necessarily apply, but imagine instead that you are invoking connect from redux.
In most use cases, connect accepts 2 configuration functions -
mapStateToProps & mapDispatchToProps - that define the behaviour. If you define those within MyComponent then any consuming component can import MyComponent from 'MyComponent' and start using it.
If you instead rely on the parent component to call connect() then you are forcing every consumer to re-implement the configuration of connect as well. That may mean many instances of duplicated configuration and adds to the complexity for consuming components.
That being said, there are certainly cases where you might want this behaviour - for example, if you wanted to connect the same component to different state definitions. Ultimately you need to pick the best pattern to support what you need from the component.

Construct React Component from a React Element

I'm trying to create a "higher-order" function in React that performs some permissions-based checks on the wrapped component and returns it accordingly.
MyComponent.js
...
export default Permissions(MyComponent)
Permissions.js
export default function Permissions(Component) {
class NewComponent extends React.Component {
// ... perform checks here
render() {
return {validPermissions && <Component />}
}
}
}
However, I'd like to be able to use this Permissions as a React Component (as opposed to a function that wraps the component export).
It would looks similar to this:
<Permissions>
<MyComponent />
</Permissions>
When I run React.Component.isPrototypeOf(Component.children) I get false in these instances. My inclination is to think that the solution is to use some React or ReactDOM method to transform the React Element into a React Component, and then perform the same checks.
How can I transform a React Element into a React Component?
Update:
I gave the bit about permissions as context, but not looking for help with regard to implementing permissions.
I am basically looking for the opposite of React.createElement(MyComponent).
You can use a functional component, which combines the best of both worlds: it's simple (just a function!) and at the same time it's a proper stateless React component.
const Permissions = ({ granted, children }) =>
granted ? React.Children.only(children) : null;
Usage:
<Permissions granted={true}>
<MyComponent />
</Permissions>

How to use PureRenderMixin (React js) in Meteor

I am building an app with Meteor 1.2 and react, and the react-meteor-data mixin to get the data from my publish methods.
I think a good idea is to have an "AppWrapper" component with all the state and data subscriptions, that passes via props to the "App" component, who will render all the components down to the hierarchy...
Although this is working, I would like to have all the render components pure and with immutable data.
What is the way to proceed?
1) There is already the addon in the react package but I don't know how to use it?
2) I should install it from npm and wait for Meteor 1.3 package system?
3) Is it possible to implement a custom shouldComponentUpdate with some immutable library?
I will appreciate any ideas or experience in this topic, thanks
1) Go to point 3
2) Go to point 3
3) Of course! As an example: Immutable.js
const AppWrapper = React.createClass({
mixins: [ReactMeteor.Mixin],
getMeteorState () {
return {
data: Immutable.Map({
userId: Meteor.userId()
})
};
},
shouldComponentUpdate (nextProps, nextState) {
return !this.state.data.equals(nextState.data);
},
render () {
return (
<App data={this.state.data} />
);
}
});
// This is basic example with pure component.
// Of course this might be another component created with
// React.createClass implementing it's own shouldComponentUpdate method.
const App = ({ data }) => (
<p>Your userId: {data.get('userId')}</p>
);

Categories

Resources