내가 수업을C++의 모의 객체는 항상 가상 메소드 또는 템플릿이 필요합니까?
class Inner {
public:
void doSomething();
};
class Outer {
public:
Outer(Inner *inner); // Dependency injection.
void callInner();
};
적절한 단위 테스트 나는 Inner
에 대한 검사를해야한다라고 가정하자. 그렇다면 Outer
/Inner
대신 Outer
이 추가 된 기능에 대한 단위 테스트를 수행 할 수 있도록 이 아닌 MockInner
을 사용하는 Outer
에 대한 테스트를 수행해야합니다. 이렇게하려면
는 Googletest이 같은 순수한 추상 클래스 (인터페이스)로 Inner
를 돌려 제시하는 것 같다
// Introduced merely for the sake of unit-testing.
struct InnerInterface {
void doSomething() = 0;
};
// Used in production.
class Inner : public InnerInterface {
public:
/* override */ void doSomething();
};
// Used in unit-tests.
class MockInner : public InnerInterface {
public:
/* override */ void doSomething();
};
class Outer {
public:
Outer(Inner *inner); // Dependency injection.
void callInner();
};
그래서, 생산 코드에서, 내가 Outer(new Inner)
을 사용; 테스트 중에는 Outer(new MockInner)
입니다.
확인. 이론적으로는 좋았지 만 코드 전체에서이 아이디어를 사용하기 시작했을 때 모든 괴물을위한 순수한 추상 클래스를 만들었습니다. 불필요한 가상 디스패치 때문에 약간의 런타임 성능 저하를 무시할 수있는 경우에도 보일러 플레이트 타이핑이 많이 있습니다.
다른 방법은 다음과 같이 템플릿을 사용하는 것입니다 : 이것은 보일러 도금 및 불필요한 가상 파견을 피할 수
class Inner {
public:
void doSomething();
};
class MockInner {
public:
void doSomething();
};
template<class I>
class Outer {
public:
Outer(I *inner);
void callInner();
};
// In production, use
Outer<Inner> obj;
// In test, use
Outer<MockInner> test_obj;
; 하지만 지금은 전체 코드베이스가 괴상한 헤더 파일에있어 소스 구현을 숨길 수 없게됩니다 (템플릿 컴파일 오류와 긴 빌드 시간은 물론입니다).
올바른 단위 테스트를 수행하는 유일한 방법은 가상 및 템플릿이라는 두 가지 방법입니까? 적절한 단위 테스트를 수행하는 더 좋은 방법이 있습니까?
적절한 단위 테스트를 통해, 나는 을 의미합니다. 각 단위 테스트는 해당 유닛에 의해 도입 된 기능 만 테스트하지만 유닛의 종속성은 테스트하지 않습니다..
저는 개인적으로 단위 테스트 순결 자들이 이상적으로 설정 한 것보다 작업 단위 테스트와 단순하고 깨끗하며 유지 보수가 가능한 디자인을 선호합니다. 나는이 반응을 좋아한다. – kirakun