[TDD] 07 - ToDoItem Component

ToDoList 컴포넌트의 자식 컴포넌트인 ToDoItem 컴포넌트의 테스트

Rendering test

앱이 의도한대로 잘 그려지고 있는가?

테스트 코드 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// __tests__/ToDoItem-test.js
...
import ToDoItem from '../src/components/ToDoItem';

describe("Rendering", () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<ToDoItem />)
})
it("Should render a Text component", () => {
expect(wrapper.find('Text')).toHaveLength(1);
});

it("Should render two buttons", () => {
expect(wrapper.find('Button')).toHaveLength(2);
})
});

테스트 결과 1

1
2
3
4
5
6
7
8
FAIL  __tests__/ToDoItem-test.js
● Test suite failed to run

Cannot find module '../src/components/ToDoItem' from 'ToDoItem-test.js'

5 | import 'react-native';
6 | import React from 'react';
> 7 | import ToDoItem from '../src/components/ToDoItem';

정의되지 않은 ToDoItem 모듈 에러 발생. 아래와 같이 컴포넌트 작성

1
2
3
4
5
6
// src/components/ToDoItem/index.js
...
const ToDoItem = () => {
return null;
}
...

테스트 결과 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 FAIL  __tests__/ToDoItem-test.js
Rendering
✕ Should render a Text component (9ms)
✕ Should render two buttons (1ms)

● Rendering › Should render a Text component

expect(received).toHaveLength(expected)

Expected length: 1
Received length: 0
Received object: {}
...
● Rendering › Should render two buttons

expect(received).toHaveLength(expected)

Expected length: 2
Received length: 0
Received object: {}

Make it green

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/components/ToDoList/index.js
...
import {View, Text, Button} from 'react-native';

const ToDoItem = () => {
return (
<View>
<Text></Text>
<Button></Button>
<Button></Button>
</View>
);
};
...

테스트 결과

1
2
3
4
PASS  __tests__/ToDoItem-test.js
Rendering
✓ Should render a Text component (536ms)
✓ Should render two buttons (1ms)

Interaction test

컴포넌트 내에서의 interaction 이 의도한대로 진행되는가?

테스트 코드 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Interaction
describe('Interaction', () => {
let wrapper;
let props;

// Complete feature
describe('Complete feature', () => {
beforeEach(() => {
props = {
index: 0,
item: {text: 'first ToDoItem', completed: false},
onCompleted: jest.fn(),
};
wrapper = shallow(<ToDoItem {...props} />);
wrapper.find('Button').at(0).prop('onPress')();
});
it("should call 'onCompleted' callback with index", () => {
expect(props.onCompleted).toHaveBeenCalledTimes(1);
expect(props.onCompleted).toHaveBeenCalledWith(props.index);
});
});

// Complete feature
describe('Delete feature', () => {
beforeEach(() => {
props = {
index: 0,
item: {text: 'first ToDoItem', completed: false},
onDeleted: jest.fn(),
};
wrapper = shallow(<ToDoItem {...props} />);
wrapper.find('Button').at(1).prop('onPress')();
});
it("should call 'onDeleted' callback with index", () => {
expect(props.onDeleted).toHaveBeenCalledTimes(1);
expect(props.onDeleted).toHaveBeenCalledWith(props.index);
});
});
});

Make it green

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const ToDoItem = ({item: completed, onCompleted, onDeleted, index = 0}) => {
function _onPress() {
onCompleted(index);
}
function _onDeleted() {
onDeleted(index);
}
return (
<View style={!completed? styles.default : styles.completed}>
<Text></Text>
<Button title="Add" onPress={_onPress}></Button>
<Button title="Delete" onPress={_onDeleted}></Button>
</View>
);
};

점점 포스팅이 귀찮아진다. 급한 성질 탓….

공유하기