模拟类来测试它的方法

时间:2013-09-27 07:37:29

标签: c++ unit-testing mocking

我想测试makeTvSeries()方法,而不是将getNumberOfShows,printMsg提取到其他类,然后嘲笑它,所以我想要模拟TvChannel类。

是否可以调用基类方法(makeTvSeries)来调用子方法:getNumberOfShows,printMsg而不去除虚拟性?所以我可以在其他测试中使用相同的模拟类definiton,例如foo.playTvSeries(mockTvChannel),并期望调用makeTvSeries?。

此外,我在做什么是好的做法?在整个程序中还有其他类使用cin和cout,正如我在开头所说,我不想将它们全部提取到一个负责输入/输出的类。你的经历和我应该做些什么?

class MockTvChannel : public TvChannel{
public:
    MOCK_METHOD0(getNumberOfShows, int());
    //MOCK_METHOD0(makeTvSeries, void());
    MOCK_METHOD0(printMsg, void());
};

TEST(sample_test_case, sample_test)
{
    MockTvChannel channel;
    EXPECT_CALL(channel, getNumberOfShows())
        .Times(1)
        .WillOnce(::testing::Return(10));

    EXPECT_CALL(channel, printMsg())
        .Times(10);

    channel.makeTvSeries();
}    


class TvChannel
{
protected:
    virtual int getNumberOfShows(){
        int nShows;
        std::cin >> nShows;
        return nShows;
    }

    virtual void printMsg(){
        std::cout << "What a show!" << std::endl;
    }

public:
    /*virtual*/ void makeTvSeries()
    {
        int nShows = getNumberOfShows();
        for(int i = 0; i<nShows; ++i){  
            printMsg();
        }
    }
    virtual ~TvChannel() {};
};

1 个答案:

答案 0 :(得分:1)

  

所以我可以在其他测试中使用相同的模拟类定义,例如foo.playTvSeries(mockTvChannel),并期望调用makeTvSeries?

是的,你可以。你的实施很好。

  

这是我做什么的好习惯吗?

是的。在SOLID principle之后,您应用了以下原则:

  • LSP:在单元测试中,您切换了实际实现并使用mock进行了测试,因此您的makeTvSerier正常工作
  • ISP:您的班级有一个界面
  • DIP:我想,你想在将mock实例传递给其他对象时使用控制反转