user2366975
user2366975

Reputation: 4710

Googletest expect_call not logging call

The testcase shall assert that the method tagcache() of a resource is called, to ensure the resource's tag cache is updated. I know that the method is called, yet the test fails because:

Expected: to be called at least once
Actual: never called - unsatisfied and active

But why?

void TagModel::tagResource(Tag *tag, Resource *r)
{
    if ( tag ){ tag->addToResource(r); }
}

void Tag::addToResource(Resource *r)
{
    if ( !r ){ return; }
    addToResource(r->id());
    r->tagcache()->add(this->id(),this->name());
}

class ResourceMock : public Resource
{
public:
    MOCK_CONST_METHOD0(tagcache,TagCache *(void));
};

TEST(tagmodel,tag_resource){
    TagModel m;
    Tag *t = m.createTag("tag");
    ResourceMock mockres;
    EXPECT_CALL(mockres,tagcache()).Times(AtLeast(1));
    m.tagResource(t,&mockres);
}

Update: Resource definition

class Resource
{
    mutable TagCache *tagcache_ = nullptr;
public:
    virtual ~Resource(){
        if ( tagcache_){ delete tagcache_; }
    }    
    TagCache *tagcache() const{
        if ( !tagcache_){
            tagcache_ = new TagCache;
        }
        return tagcache_;
    }
};

Upvotes: 0

Views: 92

Answers (2)

user2366975
user2366975

Reputation: 4710

With these changes it is working. But the test itself is not good; Too many dependencies. I should mock the TagCache as well, and maybe move TagModel to a fixture.

TEST(tagmodel,tag_resource){
    TagModel m;
    Tag *t = m.createTag("tag");
    ResourceMock mockres;
    TagCache cache;
    EXPECT_CALL(mockres,tagCache())
            .Times(AtLeast(1))
            .WillOnce(Return(&cache)); // must not return a nullptr default value, because the 'tagResource' will call the cache.
    m.tagResource(t,&mockres);
}

mutable QSharedPointer<TagCache> tagcache_;
// Would like to add 'final' keyword, but the mock must be able to override this method.
virtual TagCache *tagCache() const{
    if ( tagcache_.isNull() ){ tagcache_ = QSharedPointer<TagCache>(new TagCache); }
    return tagcache_.data();
}

Upvotes: 0

Jarod42
Jarod42

Reputation: 217970

Resource::tagcache() is not virtual, so

ResourceMock mockres;
Resource *r = &mockres;
// [..]
r->tagcache()->add(this->id(),this->name());

would call the tagcache from base class, not the one from mock.

Upvotes: 2

Related Questions