官术网_书友最值得收藏!

Submitting a form with data

The next test introduces some new concepts, so we'll break it down into its component parts. To start, add ReactTestUtils to your list of imports in test/CustomerForm.test.js:

import ReactTestUtils from 'react-dom/test-utils';

Then, begin your test with the following outline:

it('saves existing first name when submitted', async () => {
expect.hasAssertions();
});

There are two new pieces of functionality here.

The async keyword appears on the first line, just before our test function definition. This tells Jest that the test will return a promise, and that the test runner should wait for that promise to resolve before reporting on the success or failure of the test.

The hasAssertions expectation tells Jest that it should expect at least one assertion to occur. Without this line, Jest could happily pass your test if the task queue clears but your event handler was never executed. We'll see how this might occur once the test is completed.

Now, add the next part of the test into the outline, below the hasAssertions call:

render(
<CustomerForm
firstName="Ashley"
onSubmit={({ firstName }) =>
expect(firstName).toEqual('Ashley')
}
/>
);

This function call is a mix of Arrange and Assert phases in one. The Arrange phase is the render call itself. In previous tests, render has been the Act phase of our test. That means we've already tested that the form renders successfully in other tests, so we're permitted to use that functionality now as part of the Arrange phase.

The Assert phase of this code is the onSubmit handler. This is the handler that we want React to call on form submission. By defining onSubmit as a prop on the CustomerForm component, we are delegating responsibility for handling the submitted data. All the form has to do is batch up the updated data into an object and pass it on.

You'll see that there's an expectation within our handler. This is why we need the call to hasAssertions. Without the hasAssertions expectation, Jest will happily pass your test even if onSubmit never gets called: no expectation was ever run in order for your test to fail.

Finish off the test by adding in this line just below the call to render:

await ReactTestUtils.Simulate.submit(form('customer'));

The call to Simulate.submit places a React submit event on the task queue, as if a submit button had been pressed. Since this is handled asynchronously, we need to use the await keyword to ensure Jest waits before continuing to look for assertions. Once the event has been dispatched and handled, Jest will decide on the pass/fail status of the test.

We don't need a submit button on the page for this to work; raising the event is enough. Later on, we'll use another test to add the submit button.

This test is slightly confused: our render call is both the Arrange phase and the Assert phase. In the next chapter, we'll use test doubles to separate out these test phases. The method we're using here is a perfectly valid TDD practice; it's just a little messy.

Let's work on making the new test pass. This is simple despite the test itself being complicated. Change the component definition to read as follows:

export const CustomerForm = ({ firstName, onSubmit }) => {
const customer = { firstName };
return <form id="customer" onSubmit={() => onSubmit(customer)}>
<label htmlFor="firstName">First name</label>
<input
type="text"
name="firstName"
id="firstName"
value={firstName}
readOnly
/>
</form>;
};

This hooks up the form's onSubmit handler to the onSubmit function that we passed into the component, and passes it a new customer object, which includes firstName. Don't miss out the return statement and the extra curly braces that now need to be added!

Run your tests and ensure they are all passing.

主站蜘蛛池模板: 张家界市| 赤城县| 葵青区| 察雅县| 抚顺市| 读书| 博爱县| 华阴市| 赤峰市| 屏东县| 双柏县| 宜良县| 林口县| 安仁县| 竹北市| 西贡区| 东海县| 平安县| 双柏县| 聂荣县| 华宁县| 泸州市| 弥渡县| 城步| 阿克陶县| 大理市| 华坪县| 罗田县| 嘉义市| 曲周县| 肃北| 廉江市| 保山市| 石渠县| 红桥区| 温州市| 北辰区| 桐城市| 普格县| 常德市| 汪清县|