테스트 픽스처를 빌더로 교체
특히 테스트 데이터를 수동으로 정의해야 할 때 단위 테스트가 지루하고 작성하는 데 시간이 오래 걸릴 수 있다는 데 모두 동의합니다. 테스트 데이터는 모양과 크기가 모두 다를 수 있지만 많은 사람들이
test fixtures
에 가장 익숙합니다.테스트 픽스처는 기본적으로 단위 테스트의 여러 인스턴스에서 사용할 수 있는 예제 데이터 개체입니다. Javascript에서는 일반적으로
.json
파일 또는 Javascript 파일에서 개체{}
유형으로 찾을 수 있습니다.애플리케이션이 커짐에 따라 동일한 개체 유형의 다양한 변형을 사용하는 테스트 픽스처도 커질 것입니다. 이로 인해 수정하기 어렵고 특정 테스트 요구 사항에 맞출 수 있는 모호한 일회성 고정 장치가 많이 생성될 수 있습니다.
개체 어머니
Object Mother은 이 문제를 해결하는 데 도움이 될 수 있는 패턴 중 하나입니다. 이 패턴은 보다 공장과 유사한 패턴으로 이러한 고정물을 추출합니다.
var testOrder = {
order_id: 123,
line_items: [{
line_item_id: 888,
product_uuid: 'aaa-bbb-111-222'
}],
total: '10.99',
}
/* becomes */
var createSmallOrder = () => ({
order_id: 123,
line_items: [{
line_item_id: 888,
product_uuid: 'aaa-bbb-111-222'
}],
total: '10.99',
})
var createLargeOrder = () => ({
order_id: 123,
line_items: [{
line_item_id: 888,
product_uuid: 'aaa-bbb-111-222'
},
/* redacted for brevity */
{
line_item_id: 101010,
product_uuid: 'aaa-bbb-111-222'
}],
total: '100.25',
})
var OrderMother = {
createSmallOrder,
createLargeOrder
}
이 패턴은 고유한 getter 및 setter가 있는 클래스 기반 프로그래밍 언어에서 더 유용합니다. Object Mother에서 메서드를 호출하고 해당 인스턴스에만 영향을 미칠 수 있지만 Javascript 영역에서는 제대로 작동하지 않습니다.
빌더
여기에서 "빌더"를 볼 수 있습니다. 저는 팩토리 대신 "빌더"라는 단어를 사용하는 것을 좋아합니다. 팩토리는 특정 테스트 사례에 필요한 테스트 데이터를 변경하기 위해 팩토리 개체에 게터(이 경우 더 중요하게는 세터)가 있음을 상기시키기 때문입니다. . 빌더는 모든 속성을 재정의하고 불변 개체로 작업할 수 있는 새로운 새 개체를 제공합니다.
이전 예를 보면
var testOrder = {
order_id: 123,
line_items: [{
line_item_id: 888,
product_uuid: 'aaa-bbb-111-222'
}],
total: '10.99',
}
/* this would become */
const baseLineItem = {
line_item_id: 888,
product_uuid: 'aaa-bbb-111-222'
}
const baseOrder = {
order_id: 123,
line_items: [baseLineItem],
total: '10.99',
}
const aLineItem = (overrides) => ({
...baseLineItem,
...overrides,
})
const anOrder = (overrides) => ({
...baseLineItem,
...overrides,
})
이를 통해 기본적으로 테스트에 중요한 항목을 재정의할 수 있는 동시에 기본값으로 테스트 개체를 빌드할 수 있습니다. 테스트에서 총 가격이 특정 값인지 확인하는 경우 해당 값을 수동으로 설정할 수 있으며 테스트에서 해당 값이 나타날 것으로 예상합니다.
test('outputs proper total cost', () => {
const order = anOrder({ total: '19.99'})
const value = getOrderTotalFormatted(order)
expect(value).toBe('$19.99')
})
여기서 우리는
order_id
가 무엇인지 또는 line_items
가 무엇인지에 대해 신경 쓰지 않습니다. 출력이 우리가 전달하고 명시적으로 정의하는 것에 의존한다는 것을 알고 싶을 뿐입니다.특수 객체
이것은 매우 간단하고 광범위한 예이지만 특정 사용 사례의 객체라는 점에서 Object Mothers처럼 작동하는 일부 빌더를 가질 수도 있습니다.
const baseLineItem = {
line_item_id: 888,
product_uuid: 'aaa-bbb-111-222'
}
const baseOrder = {
order_id: 123,
line_items: [baseLineItem],
total: '10.99',
}
const aLineItem = (overrides) => ({
...baseLineItem,
...overrides,
})
const anOrder = (overrides) => ({
...baseLineItem,
...overrides,
})
const anEmptyOrder = () => anOrder({
line_items: [],
total: '0.00',
})
특정 속성 설정에만 관심이 있고
anEmptyOrder
와 같은 속성은 이 특수 사례와 관련이 없기 때문에 여기에서 간단한 빌더를 사용하여 order_id
를 정의하고 있습니다.변화에 탄력적
이것의 또 다른 강력한 측면은
order
개체가 shipping_method_id
와 같이 새 속성을 얻는 경우 baseOrder
만 해당 새 속성을 필요로 하고 모든 빌더가 이제 해당 속성을 갖게 된다는 것입니다!/* redacted for brevity */
const baseOrder = {
order_id: 123,
line_items: [baseLineItem],
total: '10.99',
shipping_method_id: 3
}
/* redacted for brevity */
const anEmptyOrder = () => anOrder({
line_items: [],
total: '0.00',
}) // now this will come with `shipping_method_id: 3` 🙌🏽
결론
나는 지난 몇 년 동안 빌더를 사용해 왔으며 그들은 단위 테스트 작성을 덜 고통스럽게 만들었습니다. 나는 기본 테스트 개체를 사용할 수 있고 중요한 세부 사항이 무엇인지 테스트를 읽을 때 명확한 방식으로 필요한 것을 재정의할 수 있다는 사실을 좋아합니다. 나는 당신이 이것을 시도해 볼 것을 권장하고 바라건대 이것은 당신에게도 쓰기 테스트가 조금 덜 고통스럽기를 바랍니다. #해피코딩
Reference
이 문제에 관하여(테스트 픽스처를 빌더로 교체), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/everlyhealth/replace-your-test-fixtures-with-builders-4602텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)