2017-02-20 53 views
2

創建我有這樣一羣指針參數 - >元素添加/刪除,用代碼snippt:如何期待稍後

// production code: 
Group::add(Element* e) {...}; 
Group::remove(Element* e) {...}; 
ElementDerived::ElementDerived(Group* group){ group->add(this);} 
ElementDerived::~ElementDerived(Group* group){ group->remove(this);} 

每當我想測試的類ElementDerived,我必須做到以下幾點在安裝/拆卸。但是,如何在沒有_的情況下明確設定論證期望?

// test code: 
struct Test_ElementDerived : public ::testing::Test { 
    void SetUp() override { 
    ElementDerived* p = nullptr; 
    EXPECT_CALL(group, add(_)) // how to set expection on the pointer argument? 
     .WillOnce(Invoke([&p](auto base_ptr) { 
     p = static_cast<ElementDerived*>(base_ptr); 
     })); 
    sut = std::make_unique<ElementDerived>(&group); 
    } 
    void TearDown() override { 
    EXPECT_CALL(group, remove(sut.get())); 
    } 
    MockGroup group{}; 
    std::unique_ptr<ElementDerived> sut; 
}; 
+0

期望可能應該在測試機構中設置,而不是在夾具中。 –

+0

好吧,我同意,但這是一個普遍的規則。在某些情況下,動作已經在構造函數中發生。你看到代碼片斷,這並不複雜或不合理的情況。 – pepero

+0

'EXPECT_EQ(sut.get(),p);'? – Jarod42

回答

0

你可以這樣做:

Element* p = nullptr; 
EXPECT_CALL(group, add(_)).WillOnce(SaveArg<0>(&p)); 
sut = std::make_unique<ElementDerived>(&group); 
ASSERT_EQ(p, static_cast<Element*>(sut.get())); 

這沒有什麼不同,從你剛纔做了很多。要使用一些匹配替換_ - 你必須知道的指針 - 來實現,唯一的方法是使用放置新:

struct DestructCaller { 
    template <typename T> void operator()(T* ptr) 
    { 
     if (ptr) ptr->~T(); 
    } 
}; 
std::aligned_storage_t<sizeof(ElementDerived), alignof(ElementDerived)> sut_storage; 
std::unique_ptr<ElementDerived, DestructCaller> sut; 

void SetUp() override 
{ 

    EXPECT_CALL(group, add((ElementDerived*)&sut_storage)); 
    sut.reset(new (&sut_storage) ElementDerived(&group)); 
} 

或者類似的概念有不受限制的工會:

union 
{ 
    ElementDerived sut; 
}; 

void SetUp() override 
{ 

    EXPECT_CALL(group, add(&sut)); 
    new (&sut) ElementDerived(&group); 
} 
void TearDown() override 
{ 

    EXPECT_CALL(group, remove(&sut)); 
    sut.~ElementDerived(); 
} 

在我個人觀點 - 使用SaveArg和ASSERT_EQ的方式更具可讀性。