Google mock - 多个期望中的至少一个
Google mock - at least one of multiple expectations
我正在使用 Google Mock 来为外部 API 指定兼容层。在外部 API 中,有多种方法可以执行某些操作,因此我想指定满足一组期望中的至少一个(或最好是一个)期望。在伪代码中,这就是我想要做的:
Expectation e1 = EXPECT_CALL(API, doFoo(...));
Expectation e2 = EXPECT_CALL(API, doFooAndBar(...));
EXPECT_ONE_OF(e1, e2);
wrapper.foo(...);
这可以使用 Google Mock 来实现吗?
这可以通过两种方式实现:
- 使用自定义方法执行器 - 创建一个 class,使用相同的方法。然后使用
Invoke()
将调用传递给该对象
- 使用部分顺序调用 - 在不同的序列中创建不同的期望,如所解释的 here
使用自定义方法执行器
像这样:
struct MethodsTracker {
void doFoo( int ) {
++ n;
}
void doFooAndBar( int, int ) {
++ n;
}
int n;
};
TEST_F( MyTest, CheckItInvokesAtLeastOne ) {
MethodsTracker tracker;
Api obj( mock );
EXPECT_CALL( mock, doFoo(_) ).Times( AnyNumber() ).WillByDefault( Invoke( &tracker, &MethodsTracker::doFoo ) );
EXPECT_CALL( mock, doFooAndBar(_,_) ).Times( AnyNumber() ).WillByDefault( Invoke( &tracker, &MethodsTracker::doFooAndBar ) );
obj.executeCall();
// at least one
EXPECT_GE( tracker.n, 1 );
}
使用偏序调用
TEST_F( MyTest, CheckItInvokesAtLeastOne ) {
MethodsTracker tracker;
Api obj( mock );
Sequence s1, s2, s3, s4;
EXPECT_CALL(mock, doFoo(_)).InSequence(s1).Times(AtLeast(1));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s1).Times(AtLeast(0));
EXPECT_CALL(mock, doFoo(_)).InSequence(s2).Times(AtLeast(0));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s2).Times(AtLeast(1));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s3).Times(AtLeast(0));
EXPECT_CALL(mock, doFoo(_)).InSequence(s3).Times(AtLeast(1));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s4).Times(AtLeast(1));
EXPECT_CALL(mock, doFoo(_)).InSequence(s4).Times(AtLeast(0));
obj.executeCall();
}
我正在使用 Google Mock 来为外部 API 指定兼容层。在外部 API 中,有多种方法可以执行某些操作,因此我想指定满足一组期望中的至少一个(或最好是一个)期望。在伪代码中,这就是我想要做的:
Expectation e1 = EXPECT_CALL(API, doFoo(...));
Expectation e2 = EXPECT_CALL(API, doFooAndBar(...));
EXPECT_ONE_OF(e1, e2);
wrapper.foo(...);
这可以使用 Google Mock 来实现吗?
这可以通过两种方式实现:
- 使用自定义方法执行器 - 创建一个 class,使用相同的方法。然后使用
Invoke()
将调用传递给该对象 - 使用部分顺序调用 - 在不同的序列中创建不同的期望,如所解释的 here
使用自定义方法执行器
像这样:
struct MethodsTracker {
void doFoo( int ) {
++ n;
}
void doFooAndBar( int, int ) {
++ n;
}
int n;
};
TEST_F( MyTest, CheckItInvokesAtLeastOne ) {
MethodsTracker tracker;
Api obj( mock );
EXPECT_CALL( mock, doFoo(_) ).Times( AnyNumber() ).WillByDefault( Invoke( &tracker, &MethodsTracker::doFoo ) );
EXPECT_CALL( mock, doFooAndBar(_,_) ).Times( AnyNumber() ).WillByDefault( Invoke( &tracker, &MethodsTracker::doFooAndBar ) );
obj.executeCall();
// at least one
EXPECT_GE( tracker.n, 1 );
}
使用偏序调用
TEST_F( MyTest, CheckItInvokesAtLeastOne ) {
MethodsTracker tracker;
Api obj( mock );
Sequence s1, s2, s3, s4;
EXPECT_CALL(mock, doFoo(_)).InSequence(s1).Times(AtLeast(1));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s1).Times(AtLeast(0));
EXPECT_CALL(mock, doFoo(_)).InSequence(s2).Times(AtLeast(0));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s2).Times(AtLeast(1));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s3).Times(AtLeast(0));
EXPECT_CALL(mock, doFoo(_)).InSequence(s3).Times(AtLeast(1));
EXPECT_CALL(mock, doFooAndBar(_,_)).InSequence(s4).Times(AtLeast(1));
EXPECT_CALL(mock, doFoo(_)).InSequence(s4).Times(AtLeast(0));
obj.executeCall();
}