enzyme icon indicating copy to clipboard operation
enzyme copied to clipboard

simulate() support for custom events on shallow rendered children

Open alex-e-leon opened this issue 9 years ago • 16 comments

Any thoughts on having simulate run arbitrary custom events on a shallowly rendered child? Ie ideally I'd like to be able to call simulate on any of a shallow rendered childs props that call a function.

ex calling simulate('customEvent') on <child customEvent={func}/> would runfunc()` on a shallow rendered component.

This would allow us to assert functions that might not run on standard dom events without having to write a full integration test.

We could create a new function shallowSimulate() or something if we're worried about the interactions on fully mount()ed components.

alex-e-leon avatar Jan 29 '16 01:01 alex-e-leon

@alex-e-leon I like this idea in spirit, but i'll have to think for a bit about whether or not it is a good idea or not.

In the interim, running wrapper.find(Child).prop('customEvent')(fakeEvent) will do essentially what you're asking for already...

lelandrichardson avatar Jan 29 '16 07:01 lelandrichardson

@lelandrichardson I wasn't sure this would have the correct context when calling the function but it looks like everything works. Maybe in the interim it's worth documenting this approach?

I'm not sure if it's the most obvious approach for simulating custom functions, but I'm not sure what a better api might look like either.

Thanks for your help!

alex-e-leon avatar Jan 31 '16 22:01 alex-e-leon

Just to point out here that I had the same issue trying to find out how simulating some custom event.

The solution proposed by @lelandrichardson is working perfect and solved my issue, but anyway could be really nice to have it integrated in future release ! Can't wait to be able to .simultate(noMaterWhat)

ThomasVuillaume avatar Jun 13 '17 11:06 ThomasVuillaume

@lelandrichardson can u give a demo ,thanks.

clownvary avatar Jun 19 '17 11:06 clownvary

@clownvary here's what I did based on what @lelandrichardson said:

<SubmitButtons
            isOpenCS={isEditable}
            hasCommentWritten={hasWrittenComment}
            handleTimesheetLock={this.lockTimesheet}
            timesheetData={[someData]}
            />

And if I want to simulate some "TimesheetLock" event:

const myFakeCallback = () => console.log('Do your treatment here');
const wrapper = shallow(<WrapperOfSubmitButtons/>);
wrapper.find(SubmitButtons).prop('handleTimesheetLock')(myFakeCallback)

ThomasVuillaume avatar Jun 19 '17 14:06 ThomasVuillaume

@ThomasVuillaume thanks for your demo, but i just want to test my customEvent ever had been called, and what should i do in this case?

  <CheckScrollModal
             onScrollToBottom={() => {
              this.props.hideWarningAlertAction();
            }}
          />

should i do like this ?

wrapper.find(CheckScrollModal).prop('onScrollToBottom')(()=>{console.log('test');})

clownvary avatar Jun 20 '17 02:06 clownvary

You can try this:

/* Begin of you test is it('shall do something') => { */
const propsYouWannaInject = defaultProps;
spyOn(propsYouWannaInject , 'hideWarningAlertAction').and.callThrough();
const wrapper = shallow( <CheckScrollModal {...propsYouWannaInject }/>);
wrapper.find(CheckScrollModal).prop('onScrollToBottom')();
expect(propsYouWannaInject .onScrollToBottom).toHaveBeenCalled();

SpyOn is part of Jasmine, but you can use another test lib if you want

ThomasVuillaume avatar Jun 20 '17 07:06 ThomasVuillaume

@ThomasVuillaume ,it works for me ,thank u guy 👍

clownvary avatar Jun 22 '17 06:06 clownvary

The issue is still open. Also documentation doesn't state anything obvious about this, as far as I can tell. But isn't it actually already working in current shallow rendering?

/* Film component */
render() {
  return (
    ...
    <FilmHeader onSearchClick={this.handleSearchClick}>
    ...
  )
}

/* Test */
const wrapper = shallow(<Film {...props} />);
wrapper.find('FilmHeader').simulate('searchClick');

Maybe we just need to make the documentation more obvious on the hidden magic? Or am I missing something?

dubbha avatar Oct 31 '17 10:10 dubbha

Last time I tried, this didn't work because "simulate" expected some kind of keyword known to be an event like "click", but dit not manage to do the job when you passed a word like "searchClick" in some way to expect it to find the handler with an "on" in the front.

Maybe it changed since then

ThomasVuillaume avatar Oct 31 '17 12:10 ThomasVuillaume

may be help https://github.com/airbnb/enzyme/issues/1201

palaniichukdmytro avatar Oct 31 '17 12:10 palaniichukdmytro

hey Thomas, I have tried the below syntax and it doesn't work for me.

let myWrapper = shallow(<InputWithFrequencyWrapper {...stubProps}/>
let inputElement = myWrapper.find(IncomeWithFrequencyInputComponent);
inputElement.prop('onFrequencyChange')( e=> console.log("executing the on frequency change"))
"enzyme": "^2.9.1",
    "enzyme-to-json": "^1.5.1",

I'm using enzyme 2.9.1 library.

Thanks.

khanzzirfan avatar Apr 04 '18 00:04 khanzzirfan

Hey Thomas, I actually got it work in this way.

 let myWrapper = shallow(<InputWithFrequencyWrapper {...stubProps} />);
 let inputElement = myWrapper.find(IncomeWithFrequencyInputComponent);
 expect(inputElement.props().onFrequencyChange).toEqual(myWrapper.instance().handleOnFrequencyChange);

it works as expected now. Thank you.

khanzzirfan avatar Apr 04 '18 00:04 khanzzirfan

None of the provided solution worked for me. I have parent component and child component.Child component have one custom event and that custom event bounded function coverage is not happening due to this. I have to explicitly call that function for coverage.That is wrong.

vasuneet avatar Nov 05 '19 17:11 vasuneet

My use-case is that I have React components which render custom web components. These web components trigger custom events, but unfortunately I can't use simulate to trigger custom events. Would be nice if this was possible.

simonvizzini avatar Nov 26 '19 12:11 simonvizzini

I found the simulate can trigger custom events who's name start with "on", maybe this issue can be closed. I am using "enzyme": "3.10.0",

geekeren avatar Dec 02 '20 08:12 geekeren