2010-06-15 6 views
1

새로운 프로젝트에 대한 광범위한 테스트를하고 싶지만 문제가 있습니다.TDD와 RAII를 섞어 쓰는 방법

기본적으로 MyClass를 테스트하고 싶습니다. MyClass는 필자가 테스트 목적으로 일을하고 싶지 않거나 원하는 다른 여러 클래스를 사용합니다. 그래서 mock을 만들었습니다. (테스트를 위해 gtest와 gmock을 사용합니다)

그러나 MyClass는 생성자에서 필요한 모든 것을 인스턴스화하고 소멸자에서 해제합니다. 그건 내가 생각하는 RAII이다.

그래서 모든 것을 만들고 MyClass의 생성자에게 제공하는 일종의 공장을 만들어야한다고 생각했습니다. 그 공장은 테스트 목적으로 가짜 일 수 있습니다. 하지만 더 이상 RAII가 맞지 않아?

그러면 좋은 해결책이 무엇입니까?

+0

가능한 중복 : http://stackoverflow.com/questions/195682/how-do-you-mock-classes-that-use-raii-in-c – Cogwheel

답변

2

다른 클래스를 조롱하는 것과 같은 방법으로 조롱합니다. RAII 클래스의 생성자가 처리하도록하십시오.

class MyInterface 
{ 
    virtual void MyApiFunction(int myArg) 
    { 
     ::MyApiFunction(myArg); 
    } 
}; 

class MyRAII : boost::noncopyable //Shouldn't be copying RAII classes, right? 
{ 
    MyInterface *api; 
public: 
    MyRAII(MyInterface *method = new MyInterface) 
    : api(method) 
    { 
     //Aquire resource 
    } 
    ~MyRAII() 
    { 
     //Release resource 
     delete api; 
    } 
}; 

class MockInterface : public MyInterface 
{ 
    MOCK_METHOD1(MyApiFunction, void(int)); 
}; 

TEST(Hello, Hello) 
{ 
    std::auto_ptr<MockInterface> mock(new MockInterface); 
    EXPECT_CALL(*mock, ....)...; 
    MyRAII unitUnderTest(mock.release()); 
} 
+0

나는 방법에 대한 기본 값이 무엇을 가정하자 여기서 RAII 컨텍스트에서 확인합니다 ... 그러나 MyRAII 사용자에게는 MyInterface에 대한 종속성이 생깁니다. –

+0

@ f4 : 음, MyRAII는 MyInterface에 의존합니다. 그렇지 않으면 어떻게 기대하니? 기본 인수로 숨길 수도 있고 여러 생성자로 숨길 수도 있습니다. 그러나 MyRAII는 모의 수업을 어떻게 든 할 수 있어야합니다. 팩토리 메서드로 변경해도 문제가 해결되지 않습니다. 팩터 리 메서드는 여전히 어떤 메서드를 만들지 알아야합니다. –

+0

나는 MyRAII의 사용자를 의미합니다. 그들은 MyRAII가 MyInterface를 사용한다는 것을 알 필요가 없으며 MyInterface.h에 의존 할 필요가 없습니다. 그렇게하려면 #include "MyInterface.h"가 있어야합니다. 공장 정보 나는 "그 공장은 테스트 목적으로 가짜 일 수있다"라고 썼다. 실제 개체 대신 모의 개체를 만들어 MyRAII 생성자에게줍니다. 잘못 이해하지 마라. 나는 당신의 솔루션이 마음에 든다. MyInterface에서 의미하는 (물리적 인) 의존성에 대해서만 염려했다. 나는 그것이 MyRAII의 내부 작용을 공개하고있는 것처럼 느낀다 : 나는 불필요한 것을 피하려고 노력하고있다. –