- Mastering React Test:Driven Development
- Daniel Irvine
- 610字
- 2021-06-24 14:45:03
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.
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.
- SQL Server 從入門到項目實踐(超值版)
- Angular UI Development with PrimeNG
- Boost C++ Application Development Cookbook(Second Edition)
- 基于Java技術的Web應用開發
- 網絡爬蟲原理與實踐:基于C#語言
- 飛槳PaddlePaddle深度學習實戰
- 大學計算機基礎實驗指導
- jQuery Mobile移動應用開發實戰(第3版)
- JavaScript動態網頁編程
- Raspberry Pi Robotic Projects(Third Edition)
- Scala編程實戰
- 人人都能開發RPA機器人:UiPath從入門到實戰
- 計算機程序的構造和解釋(JavaScript版)
- 網絡綜合布線與組網實戰指南
- 軟件開發中的決策:權衡與取舍