테스트 대역 (Test Double)
정의
- xUnit Test Patterns의 저자인 제라드 메스자로스(Gerard Meszaros)가 만든 용어로
테스트를 진행하기 어려운 경우 이를 대신해 테스트를 진행할 수 있도록 만들어주는 객체
를 말한다.- ex) DB로 부터 조회한 값을 연산하는 로직을 구현했다고 치자.
- 로직을 실행하기 위해선 항상 DB를 참조하기 때문에 DB상태에 따라서 결과가 달라질 수 있다.
종류
- Fake
- Stub
- Mock
- Dummy
- Spy
Test Double - None
- product code
public class ControlCenter
{
private readonly Car car;
public ControlCenter(Car car)
{
this.car = car;
}
public void SwitchOn()
{
car.TurnOn();
}
}
public class Car
{
private readonly string CarNumber;
public bool CanMove { get; private set; }
public Car(string carNumber)
{
CarNumber = carNumber;
CanMove = false;
}
public void TurnOn()
{
CanMove = true;
}
public string GetNumber()
{
return CarNumber;
}
}
- 테스트 코드
[Fact]
public void TestControlCenterSwitchOn()
{
string carNo = "123호 1134";
Car car = new Car(carNo);
Controller controller = new Controller(car);
//act
controller.SwitchOn();
//assert
Assert.True(car.CanMove);
Assert.Equal(carNo, car.GetNumber());
}
Test Double - Fake
- Fake는 실제로 동작하는 구현을 가진 객체
- 테스트 중에 실제 컴포넌트를 대체하기 위해 사용된다.
- 장점: 실제 DB 또는 외부 서비스를 사용하지 않아도 테스트가 가능하다.
- 단점: 실제 프로덕션 코드와 완전히 동일하지 않을 수 있다. 프로덕션 코드에선 예상치 못한 문제 발생할 수 있다.
- 프로덕션 코드
public class Controller
{
private readonly ICar car;
public Controller(ICar car)
{
this.car = car;
}
...
public interface ICar
{
void TurnOn();
string GetNumber();
}
public class FakeCar : ICar
{
public bool CanMove { get; private set; }
public void TurnOn()
{
CanMove = true;
}
public string GetNumber()
{
return "TEST";
}
}
- 테스트 코드
[Fact]
public void SwitchOn_Should_TurnOnCarAndTruck_UsingFake()
{
string carNo = "TEST";
var fakeCar = new FakeCar(carNo);
var controller = new Controller(fakeCar);
// Act
controller.SwitchOn();
// Assert
Assert.True(fakeCar.CanMove);
Assert.Equal(carNo, fakeCar.GetNumber());
}
- FakeCar 클래스는 ICar 인터페이스를 구현하면서 실제 동작을 수행한다.
Test Double - Stub
- Stub은 메서드 호출에 대한 간단한 값을 반환하는 데 사용되는 코드
- 장점: 간단하게 구현할 수 있고, 메서드 호출의 흐름을 테스트하는 데에 용이하다.
- 단점: 실제 동작을 대체하는 데 사용되므로, 실제 동작과 다를 수 있다.
- 프로덕션 코드
public class StubCar : ICar
{
public bool CanMove { get; private set; }
public void TurnOn()
{
CanMove = true;
}
public string GetNumber()
{
return "TEST";
}
}
- 테스트 코드
[Fact]
public void SwitchOn_Should_TurnOnCarAndTruck_UsingStub()
{
// Arrange
string carNo = "TEST";
var stubCar = new StubCar();
var controller = new Controller(stubCar);
// Act
controller.SwitchOn();
// Assert
Assert.True(stubCar.CanMove);
Assert.Equal(carNo, stubCar.GetNumber());
}
- Fake와 차이점은 Stub은 단순한 메서드 호출이다.
Test Double - Mock
- 특정 동작이나 상태를 시뮬레이션하고 검증하는 데 사용
- 일반적으로 실제 객체의 동작 여부 or 호출 횟수 등을 확인할 수 있다.
- 프로덕션 코드
[Fact]
public void SwitchOn_Should_TurnOnCar_UsingMock()
{
// Arrange
var fakeCarMock = new Mock<ICar>();
var controller = new Controller(fakeCarMock.Object);
// Act
controller.SwitchOn();
// Assert
fakeCarMock.Verify(c => c.TurnOn(), Times.Once);
}
- SwitchOn() 실행 여부를 확인할 수 있습니다.
'프로그래밍' 카테고리의 다른 글
[디자인패턴] 전략패턴 (Strategy Pattern) (0) | 2024.01.03 |
---|---|
[레거시 코드 활용 전략] ch12. 클래스 의존 관계, 반드시 없애야할까? (1) | 2024.01.02 |
정규 표현식 변환 시 유용한 사이트 (0) | 2023.11.17 |
[클린코드] 10,11장 정리 (0) | 2023.11.01 |
[클린코드] 11장 시스템 (0) | 2023.10.29 |