Googletest expect_call 未记录通话
Googletest expect_call not logging call
测试用例应断言调用了资源的方法tagcache()
,以确保更新资源的标记缓存。我知道调用了该方法,但测试失败,因为:
Expected: to be called at least once
Actual: never called - unsatisfied and active
但是为什么呢?
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);
}
更新:资源定义
class Resource
{
mutable TagCache *tagcache_ = nullptr;
public:
virtual ~Resource(){
if ( tagcache_){ delete tagcache_; }
}
TagCache *tagcache() const{
if ( !tagcache_){
tagcache_ = new TagCache;
}
return tagcache_;
}
};
Resource::tagcache()
不是 virtual
,所以
ResourceMock mockres;
Resource *r = &mockres;
// [..]
r->tagcache()->add(this->id(),this->name());
会从基础 class 中调用 tagcache
,而不是从 mock 中调用 tagcache
。
通过这些更改,它正在运行。但是测试本身并不好;太多的依赖。我也应该模拟 TagCache,并可能将 TagModel 移动到固定装置。
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();
}
测试用例应断言调用了资源的方法tagcache()
,以确保更新资源的标记缓存。我知道调用了该方法,但测试失败,因为:
Expected: to be called at least once
Actual: never called - unsatisfied and active
但是为什么呢?
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);
}
更新:资源定义
class Resource
{
mutable TagCache *tagcache_ = nullptr;
public:
virtual ~Resource(){
if ( tagcache_){ delete tagcache_; }
}
TagCache *tagcache() const{
if ( !tagcache_){
tagcache_ = new TagCache;
}
return tagcache_;
}
};
Resource::tagcache()
不是 virtual
,所以
ResourceMock mockres;
Resource *r = &mockres;
// [..]
r->tagcache()->add(this->id(),this->name());
会从基础 class 中调用 tagcache
,而不是从 mock 中调用 tagcache
。
通过这些更改,它正在运行。但是测试本身并不好;太多的依赖。我也应该模拟 TagCache,并可能将 TagModel 移动到固定装置。
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();
}