将模拟类添加到stl容器

时间:2018-06-19 22:30:10

标签: c++ stl googletest googlemock

我正在对包含对象向量的类编写单元测试。我一直在尝试模拟向量中的对象,但是我一直遇到覆盖基类的问题。
示例代码:

book.hpp

class Book {
    std::string _author;
    std::string _title;

    virtual std::string getBookLabel() {
        ostringstream ostream;
        ostream << _title << " " << _author << std::endl;
        return ostream.str();
    } 
};

library.hpp

class Library {
    std::vector< Book > _books;

    std::string getBookLabels() {
       ostringstream ostream;
       for( auto i : _books ) {
           ostream << i.getBookLabel();
       }
       return ostream.str()
    }

    void addBook( Book &book ) {
       _books.push_back(book);
    }
};

test_library.cpp

TEST_F(TEST,test_get_book_labels) {
   class MockBook : public Book{
        MOCK_METHOD0(getLabel,std::string());
   };

   Library library;
   MockBook mockBook;
   EXPECT_CALL(mockBook,getLabel).
         WillOnce(Return(std::string("MockLabel")));
   Library.addBook(mockBook);

   std::string expected = "MockLabel";
   std::string actual = library.getBookLabels();
   ASSERT_EQ(expected, actual);
   // fails, actual contains "" because getBookLabels()
   // called Book::getBookLabel() instead of 
   // Mock::getBookLabel()

有没有办法让Library :: GetBookLabels()调用MockBook :: GetBookLabel()?

最新编辑:我很惊讶这不是一个更常见的问题,这就是为什么我希望我缺少一些gmock功能。

2 个答案:

答案 0 :(得分:1)

不。 std::vector<Book>只能容纳Book的实例。它永远无法保存MockBook的实例。

您可以通过拥有一个指针向量(可以指向Book或MockBook对象)来解决此问题。如果您想走这条路,我建议您使用std::vector<std::unique_ptr<Book>>而不是std::vector<Book*>之类的东西,以避免意外的内存泄漏等。 (如果还没有,请了解unique_ptr

但是,在这种情况下,您真的需要嘲笑吗?为什么不创建具有所需标签的普通Book

答案 1 :(得分:0)

如何将Library用作模板,如

template <class TBook>
class GenericLibrary { ... } ;

然后进行typedef或更现代的using

using Library = GenericLibrary<Book>;

在您的应用程序代码中,它将像以前一样进行编译。

在单元测试中,您要做的是

using MockLibrary = GenericLibrary<MockBook>;