Creating fake test events with Typescript + Jest

Evan Teague
2 min readJun 13, 2018

--

tl;dr: If you’re writing unit tests with Typescript and want to mock fake React events, look here for the React types and here for DOM types. When constructing the fake event, work backwards adding types, making sure to use the “as” operator when necessary so you don’t have to add every single property of each type.

Say you’re like me and you just started working on a project using the hottest new technologies in the Javascript world: Typescript, React, Jest, and Enzyme. You’re writing a component that contains some HTML that relies on events. For this example, I’m going to use an HTML input tag for file upload.

Here’s the sample parent component with the click handler:

Here’s the child component with the actual HTML input element:

Notice the event the onChange handler takes is of type “ChangeEvent.” Now, say I want to write some unit tests that mock this event. Here’s how you would do it:

To create the fake event object on line 23, it’s probably best to work backwards. You’ll need to look up the types here. Search for whatever package you need, but in this case we’ll look up “react.” Because we’re creating a ChangeEvent, look at the type. This ChangeEvent extends the SyntheticEvent.

You may be asking yourself “what is going on with casting the event to a ChangeEvent?” Normally with typescript, you’d apply a type to a variable by doing something like:

const event: React.ChangeEvent<HTMLInputElement> = {…}

However, Typescript doesn’t like this. It’s going to ask you to basically add every one of the fields listed on the SyntheticEvent (i.e. bubbles, cancelable, defaultPrevented, etc…). We cast it using the “as,” which you can read more about here, and this allows you to bypass all of that extra cruft it previously wanted you to add.

Next up is the fileList on line 17. I found that it is the result of event.currentTarget.files just by logging things to the browser console (trust me). FileList isn’t a react type, rather an HTML DOM type, which can be seen here. Now, I don’t know why it is like it is, but basically FileList expects a length, a function called “item,” and a key-value pair of 0 -> file.

(Why is there this weird function called “item” that doesn’t even contain the file? I don’t know, maybe you have a better grasp of the underlying nature of javascript than me.)

We’re using the regular typescript const fileList: FileList here instead of the “as” operator because all of the field are easily mockable.

Moving on.

Lastly, to mock the file variable on line 12, look at the type definition here. We‘re casting it using “as” so we don’t have to add some of the other “blob” fields.

That’s it! We’ve successfully mocked a React event in a Jest unit test.

--

--