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

Backtracking on ourselves

There's only one piece of shared state that our tests use and that's document. It must not be getting cleared each time the tests are run, and so we see the output of each test inside the document.

Even if we fixed our production code to remove the hard-coding, it still wouldn't pass; instead, we'd see the text AshleyJordan.

One solution is to clear the document DOM tree before each test run. But there's a simpler solution: we can rework our tests to not append our container element to the DOM at all, and instead work directly with the container element. In other words, we can change our expectation to check not document.body.textContent but container.textContent.

There may come a time that we actually need to attach our nodes to the DOM, and at that point, we'll need to fix this problem properly. But for now, you ain't gonna need it. So, let's solve this by avoiding the DOM tree altogether. It's the simplest way forward.

Unfortunately, there's a problem. We're in the middle of a red test. We should never refactor, rework, or otherwise change course while we're red.

What we'll have to do is ignore, or pend, this test we're working on. We do that by changing the word it to it.skip. Do that now for the second test:

it.skip('renders another customer first name', () => {

Run tests. You'll see Jest ignores the second test, and the first one still passes:

PASS test/Appointment.test.js
Appointment
? renders the customer first name (19ms)
○ skipped 1 test

Test Suites: 1 passed, 1 total
Tests: 1 skipped, 1 passed, 2 total

For this refactor, we need to make two changes:

  • Change the expectation to match on container.textContent.
  • Remove the line that calls appendChild on the document body.

We can also take this opportunity to inline the component variable. Change the test to read as follows:

it('renders the customer first name', () => {
const customer = { firstName: 'Ashley' };
const container = document.createElement('div');
ReactDOM.render(<Appointment customer={customer} />, container);
expect(container.textContent).toMatch('Ashley');
});

Run your tests: the result should be the same as earlier, with one passing test and one skipped.

It's time to bring that second test back in, by removing the .skip from the function name, and this time, let's update the test code to make the same changes we made in the first, as follows:

it('renders another customer first name', () => {
const customer = { firstName: 'Jordan' };
const container = document.createElement('div');
ReactDOM.render(<Appointment customer={customer} />, container);
expect(container.textContent).toMatch('Jordan');
});

Running tests now should give us the error that we were originally expecting:

FAIL test/Appointment.test.js
Appointment
? renders the customer first name (18ms)
? renders another customer first name (8ms)

● Appointment ? renders another customer first name

expect(received).toMatch(expected)

Expected value to match:
"Jordan"
Received:
"Ashley"

To fix this, we need to introduce the variable and use it within our JSX, which supports embedding JavaScript expressions within elements. We can also use destructuring assignment to avoid creating unnecessary variables.

Change the definition of Appointment to look as follows:

export const Appointment = ({ customer }) => (
<div>{customer.firstName}</div>
);

Note that I haven't fully destructured this. I could have written this function like this:

export const Appointment = ({ customer: { firstName } }) => (
<div>{firstName}</div>
);

The first version is no longer than the second; however, if you're counting tokens, it has one less set of curly braces. The most concise solution always wins!

Run tests; we expect this test to now pass, as follows:

PASS test/Appointment.test.js
Appointment
? renders the customer first name (21ms)
? renders another customer first name (2ms)

Great work! We're done with our passing test.

主站蜘蛛池模板: 辽阳县| 巫山县| 日喀则市| 九江县| 昭平县| 宁蒗| 林口县| 七台河市| 沾化县| 延川县| 枣强县| 苏尼特左旗| 许昌县| 方正县| 太原市| 江孜县| 武城县| 甘孜| 革吉县| 绍兴县| 抚宁县| 濮阳县| 图木舒克市| 皋兰县| 赤壁市| 渑池县| 庆阳市| 宜川县| 新沂市| 威远县| 阜新| 民权县| 九龙县| 洮南市| 城口县| 财经| 凌海市| 灵宝市| 钟祥市| 乃东县| 额济纳旗|