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

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.

主站蜘蛛池模板: 洪泽县| 江阴市| 裕民县| 双柏县| 文成县| 乐都县| 广水市| 建平县| 桂林市| 滨海县| 张家界市| 嘉定区| 罗田县| 新巴尔虎左旗| 轮台县| 绥滨县| 新田县| 澜沧| 新蔡县| 九龙坡区| 旺苍县| 西吉县| 民丰县| 淳安县| 灵山县| 克山县| 嫩江县| 上思县| 囊谦县| 兰坪| 根河市| 长宁区| 泸溪县| 舞钢市| 永靖县| 柞水县| 锦州市| 工布江达县| 昌邑市| 苏州市| 伊宁县|