- Mastering React Test:Driven Development
- Daniel Irvine
- 408字
- 2021-06-24 14:45:05
Specifying list items
Now, let's fill in the list items for the ol element we just rendered.
- Create a third test in the new describe block, with this content:
it('renders each appointment in an li', () => {
const today = new Date();
const appointments = [
{ startsAt: today.setHours(12, 0) },
{ startsAt: today.setHours(13, 0) }
];
render(<AppointmentsDayView appointments={appointments} />);
expect(container.querySelectorAll('li')).toHaveLength(2);
expect(
container.querySelectorAll('li')[0].textContent
).toEqual('12:00');
expect(
container.querySelectorAll('li')[1].textContent
).toEqual('13:00');
});
Jest will show the following error:
Expected length: 2
Received length: 0
Received object: []
58 | render(<Appointments appointments={appointments} />);
59 | expect(container.querySelectorAll('li')).toHaveLength(2);
> 60 | ^
Change that div element into an li element:
<ol>
{appointments.map(appointment => (
<li key={appointment.startsAt} />
))}
</ol>
You'll see the following error from Jest:
expect(received).toEqual(expected)
Difference:
- Expected
+ Received
- 12:00
+
59 | expect(container.querySelectorAll('li')[0].textContent)
> 60 | .toEqual('12:00');
| ^
61 | expect(container.querySelectorAll('li')[1].textContent)
62 | .toEqual('13:00');
63 | });
- Add the following function to src/Appointment.js that converts a Unix timestamp (which we get from the return value from setHours) into a time of day. It doesn't matter where in the file you put it; I usually like to define constants before I use them, so this would go at the top of the file:
const appointmentTimeOfDay = startsAt => {
const [h, m] = new Date(startsAt).toTimeString().split(':');
return `${h}:${m}`;
}
This uses the destructuring assignment and template literals, which are both space-saving features that you should start using if they aren't already part of your toolbox.
TDD can help us to overcome the fear of using complicated language features. If we're ever unsure what production code does, we can simply look at the tests to tell us.
TDD can help us to overcome the fear of using complicated language features. If we're ever unsure what production code does, we can simply look at the tests to tell us.
- Use the previous function to update AppointmentsDayView, as follows:
<ol>
{appointments.map(appointment => (
<li key={appointment.startsAt}>
{appointmentTimeOfDay(appointment.startsAt)}
</li>
))}
</ol>
Running tests should show everything as green:
PASS test/Appointment.test.js
Appointment
? renders the customer first name (19ms)
? renders another customer first name (2ms)
AppointmentsDayView
? renders a div with the right id (7ms)
? renders multiple appointments in an ol element (13ms)
? renders each appointment in an li (4ms)
- This is a great chance to refactor. Both of our AppointmentsDayView tests use the same datasets. These can be lifted out into the describe scope, the same way we did with customer in the Appointment tests. This time, however, they can remain as const declarations as they never change.
To do that, move the today and appointments definitions from one of the tests to the top of the describe block, above beforeEach. Then, delete the definitions from both tests.
推薦閱讀
- 極簡算法史:從數學到機器的故事
- Cocos2d Cross-Platform Game Development Cookbook(Second Edition)
- 一步一步學Spring Boot 2:微服務項目實戰
- Kali Linux Web Penetration Testing Cookbook
- AngularJS深度剖析與最佳實踐
- 信息安全技術
- 名師講壇:Java微服務架構實戰(SpringBoot+SpringCloud+Docker+RabbitMQ)
- Unity Shader入門精要
- Haxe Game Development Essentials
- Building Business Websites with Squarespace 7(Second Edition)
- R的極客理想:量化投資篇
- Learning Cocos2d-JS Game Development
- 邊做邊學深度強化學習:PyTorch程序設計實踐
- 流程讓管理更高效:流程管理全套方案制作、設計與優化
- 大學計算機基礎