테스트 더블(Test double)은 소프트웨어 테스트에서 실제 의존 객체를 대신하여 사용되는 객체로, 모의(mock), 스텁(stub), 가짜(fakes), 스파이(spy) 등이 있다.
스텁(Stub)
스텁은 메서드 호출에 대한 미리 정의된 응답을 제공하여 어떤 동작을 시뮬레이션하는 데 사용된다. Go 언어에서는 테스트 더블에 대한 지원이 내장되어 있지 않기 때문에 흔히 인터페이스를 사용하여 스텁을 구현한다.
예를 들어, 데이터베이스 연결을 스텁으로 대체하여 특정 쿼리에 대해 미리 정의된 결과를 반환하는 방법은 다음과 같이 할 수 있다.
type DatabaseStub struct{}
func (d *DatabaseStub) Query(query string) string {
if query == "SELECT * FROM users" {
return "User1, User2"
}
return ""
}
모의(Mock)
모의는 특정 호출에 대한 기대 동작을 미리 지정하여 검증하는 데 사용된다. Go 언어에서는 일반적으로 testify/mock
패키지를 활용하여 모의를 구현한다.
예를 들어, HTTP 클라이언트의 Get
메서드 호출에 대한 모의를 만들고, 해당 호출이 한 번 일어났는지 확인하는 방법은 다음과 같이 할 수 있다.
type HTTPClientMock struct {
mock.Mock
}
func (m *HTTPClientMock) Get(url string) {
m.Called(url)
}
가짜(Fake)
가짜는 실제 객체를 대체하는 대신 실제 동작을 시뮬레이션하는 데 사용된다. Go 언어에서 파일 시스템을 가짜로 대체하는 등 다양한 가짜를 사용할 수 있다.
예를 들어, 파일 시스템 가짜를 사용하여 테스트용 파일 시스템을 생성하고, 실제 파일 시스템에 영향을 주지 않고 테스트 데이터를 조작하는 방법은 다음과 같이 할 수 있다.
type FakeFileSystem struct{}
func (f *FakeFileSystem) CreateFile(name string) {
// 가짜 파일 시스템 동작 구현
}
스파이(Spy)
스파이는 특정 메서드 호출에 대한 정보를 기록하고 이를 테스트에서 확인하는 데 사용된다. Go 언어에서는 간단한 구조체나 함수를 사용하여 스파이를 구현할 수 있다.
예를 들어, 특정 함수 호출이 정확히 한 번 일어났는지 확인하는 스파이를 만드는 방법은 다음과 같이 할 수 있다.
type FunctionSpy struct {
callCount int
}
func (s *FunctionSpy) Call() {
s.callCount++
}
테스트 더블은 소프트웨어 테스트에서 중요한 개념이며, Go 언어에서도 이를 구현하는 여러 방법을 제공한다. 적절한 상황에 맞는 테스트 더블을 사용하여 효과적인 테스트를 작성하는 것이 중요하다.
참고 문헌
- https://ieftimov.com/post/mocking-in-golang/
- https://github.com/stretchr/testify