在使用 googletest 进行模拟时,如何为重载方法指定 internal::AnythingMatcher 的参数类型?
While mocking with googletest, how to specify the argument type of an internal::AnythingMatcher for overloaded methods?
初始问题
在使用 googletest 进行测试时,我使用了一个模拟 class,其中包含一个重载方法,其中一个参数的类型不同。
当我这样做时,这会导致模棱两可的函数调用
EXPECT_CALL(mockedClass,mockedMethod(_,_)).WillOnce(Return(true));
我试图通过用 An<type>()
、TypedEq<type>(_)
或 Matcher<type>(_)
替换有问题的参数以及写一些东西来将 internal::AnythingMatcher
下划线与类型规范结合起来喜欢:
Matcher<type> customAnythingMatcher = _;
EXPECT_CALL(mockedClass,mockedMethod(_,customAnythingMatcher)).WillOnce(Return(true));
一切都无济于事。
任何提示如何消除该调用的歧义?
更新#1
根据要求,我通过提供一个最小的工作——或者在这种情况下是一个非工作——示例来详细说明我正在努力实现的目标:
myInterfaceToMock.h
#ifndef MYINTERFACETOMOCK_H
#define MYINTERFACETOMOCK_H
#include <QVariant>
#include <QtGlobal>
class MyInterfaceToMock {
virtual bool myMethod(QVariant &firstArgument,
const quint8 secondArgument) const = 0;
virtual bool myMethod(QByteArray &firstArgument,
const quint16 secondArgument) const = 0;
virtual bool myOtherMethod(quint8 firstAndOnlyArgument) const = 0;
};
#endif // MYINTERFACETOMOCK_H
myMock.h
#ifndef MYMOCK_H
#define MYMOCK_H
#include <gmock/gmock.h>
#include <QtCore/QObject>
#include "myInterfaceToMock.h"
class MyMock : public MyInterfaceToMock {
public:
// virtual bool myMethod(QVariant &firstArgument, const quint8 secondArgument)
// const = 0;
MOCK_METHOD(bool, myMethod, (QVariant &, const quint8), (const, override));
// virtual bool myMethod(QByteArray &firstArgument, const quint16
// secondArgument) const = 0;
MOCK_METHOD(bool, myMethod, (QByteArray &, const quint16), (const, override));
// virtual bool myOtherMethod(quint8 firstAndOnlyArgument) const = 0;
MOCK_METHOD(bool, myOtherMethod, (quint8), (const, override));
};
#endif // MYMOCK_H
main.cpp
#include <gmock/gmock-matchers.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <QCoreApplication>
#include <QTimer>
class Tester : public QObject {
Q_OBJECT
public:
Tester(QObject *parent = nullptr) : QObject(parent) {}
public slots:
void run() {
::testing::InitGoogleTest();
emit(result(RUN_ALL_TESTS()));
}
signals:
void result(int res);
};
#include "main.moc"
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
::testing::InitGoogleMock(&argc, argv);
Tester *tester = new Tester(&app);
QObject::connect(tester, &Tester::result, &app, &QCoreApplication::exit);
QTimer::singleShot(0, tester, SLOT(run()));
return app.exec();
}
#include "myMock.h"
TEST(myTest, testMockOverload) {
using namespace testing;
MyMock mock;
// Reference method, which does work all the time
EXPECT_CALL(mock, myOtherMethod(_)).WillRepeatedly(Return(false));
// Using a defined value as argument
QVariant myVariant;
EXPECT_CALL(mock, myMethod(myVariant, 3)).WillOnce(Return(true));
bool result = mock.myMethod(myVariant, 3);
ASSERT_TRUE(result);
// Anything matcher for the unambiguous argument
EXPECT_CALL(mock, myMethod(myVariant, _)).WillOnce(Return(true));
result = mock.myMethod(myVariant, 3);
ASSERT_TRUE(result);
// Trying to match any passed qvariant
EXPECT_CALL(mock, myMethod(An<QVariant>(), _)).WillOnce(Return(true));
}
最后一行发出编译器错误:
..\googlemock_disambiguate\main.cpp(55): error C2664: 'testing::internal::MockSpec<bool (QByteArray &,quint16)> MyMock::gmock_myMethod(const testing::internal::WithoutMatchers &,const testing::internal::Function<bool (QByteArray &,quint16)> *) const': cannot convert argument 1 from 'testing::Matcher<QVariant>' to 'const testing::Matcher<QVariant &> &'
..\googlemock_disambiguate\main.cpp(55): note: Reason: cannot convert from 'testing::Matcher<QVariant>' to 'const testing::Matcher<QVariant &>'
..\googlemock_disambiguate\main.cpp(55): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
我猜它可能有某事。与方法的常量性有关,但我仍然不明白该错误的含义...
使用 An<type>
是正确的解决方案。
EXPECT_CALL(mockedClass,mockedMethod(_, An<type>())).WillOnce(Return(true));
如果它对您不起作用,则问题出在其他地方。也许你可以详细说明一下?
自己回答问题:
我只是没有正确指定类型,因为我希望通过引用。我总是尝试使用 An<type>()
之类的东西,而我应该使用 An<type&>()
来代替。
所以,根据我上面的例子,正确的行是:
EXPECT_CALL(mock, myMethod(An<QVariant&>(), _)).WillOnce(Return(true));
初始问题
在使用 googletest 进行测试时,我使用了一个模拟 class,其中包含一个重载方法,其中一个参数的类型不同。
当我这样做时,这会导致模棱两可的函数调用
EXPECT_CALL(mockedClass,mockedMethod(_,_)).WillOnce(Return(true));
我试图通过用 An<type>()
、TypedEq<type>(_)
或 Matcher<type>(_)
替换有问题的参数以及写一些东西来将 internal::AnythingMatcher
下划线与类型规范结合起来喜欢:
Matcher<type> customAnythingMatcher = _;
EXPECT_CALL(mockedClass,mockedMethod(_,customAnythingMatcher)).WillOnce(Return(true));
一切都无济于事。 任何提示如何消除该调用的歧义?
更新#1
根据要求,我通过提供一个最小的工作——或者在这种情况下是一个非工作——示例来详细说明我正在努力实现的目标:
myInterfaceToMock.h
#ifndef MYINTERFACETOMOCK_H
#define MYINTERFACETOMOCK_H
#include <QVariant>
#include <QtGlobal>
class MyInterfaceToMock {
virtual bool myMethod(QVariant &firstArgument,
const quint8 secondArgument) const = 0;
virtual bool myMethod(QByteArray &firstArgument,
const quint16 secondArgument) const = 0;
virtual bool myOtherMethod(quint8 firstAndOnlyArgument) const = 0;
};
#endif // MYINTERFACETOMOCK_H
myMock.h
#ifndef MYMOCK_H
#define MYMOCK_H
#include <gmock/gmock.h>
#include <QtCore/QObject>
#include "myInterfaceToMock.h"
class MyMock : public MyInterfaceToMock {
public:
// virtual bool myMethod(QVariant &firstArgument, const quint8 secondArgument)
// const = 0;
MOCK_METHOD(bool, myMethod, (QVariant &, const quint8), (const, override));
// virtual bool myMethod(QByteArray &firstArgument, const quint16
// secondArgument) const = 0;
MOCK_METHOD(bool, myMethod, (QByteArray &, const quint16), (const, override));
// virtual bool myOtherMethod(quint8 firstAndOnlyArgument) const = 0;
MOCK_METHOD(bool, myOtherMethod, (quint8), (const, override));
};
#endif // MYMOCK_H
main.cpp
#include <gmock/gmock-matchers.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <QCoreApplication>
#include <QTimer>
class Tester : public QObject {
Q_OBJECT
public:
Tester(QObject *parent = nullptr) : QObject(parent) {}
public slots:
void run() {
::testing::InitGoogleTest();
emit(result(RUN_ALL_TESTS()));
}
signals:
void result(int res);
};
#include "main.moc"
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
::testing::InitGoogleMock(&argc, argv);
Tester *tester = new Tester(&app);
QObject::connect(tester, &Tester::result, &app, &QCoreApplication::exit);
QTimer::singleShot(0, tester, SLOT(run()));
return app.exec();
}
#include "myMock.h"
TEST(myTest, testMockOverload) {
using namespace testing;
MyMock mock;
// Reference method, which does work all the time
EXPECT_CALL(mock, myOtherMethod(_)).WillRepeatedly(Return(false));
// Using a defined value as argument
QVariant myVariant;
EXPECT_CALL(mock, myMethod(myVariant, 3)).WillOnce(Return(true));
bool result = mock.myMethod(myVariant, 3);
ASSERT_TRUE(result);
// Anything matcher for the unambiguous argument
EXPECT_CALL(mock, myMethod(myVariant, _)).WillOnce(Return(true));
result = mock.myMethod(myVariant, 3);
ASSERT_TRUE(result);
// Trying to match any passed qvariant
EXPECT_CALL(mock, myMethod(An<QVariant>(), _)).WillOnce(Return(true));
}
最后一行发出编译器错误:
..\googlemock_disambiguate\main.cpp(55): error C2664: 'testing::internal::MockSpec<bool (QByteArray &,quint16)> MyMock::gmock_myMethod(const testing::internal::WithoutMatchers &,const testing::internal::Function<bool (QByteArray &,quint16)> *) const': cannot convert argument 1 from 'testing::Matcher<QVariant>' to 'const testing::Matcher<QVariant &> &'
..\googlemock_disambiguate\main.cpp(55): note: Reason: cannot convert from 'testing::Matcher<QVariant>' to 'const testing::Matcher<QVariant &>'
..\googlemock_disambiguate\main.cpp(55): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
我猜它可能有某事。与方法的常量性有关,但我仍然不明白该错误的含义...
使用 An<type>
是正确的解决方案。
EXPECT_CALL(mockedClass,mockedMethod(_, An<type>())).WillOnce(Return(true));
如果它对您不起作用,则问题出在其他地方。也许你可以详细说明一下?
自己回答问题:
我只是没有正确指定类型,因为我希望通过引用。我总是尝试使用 An<type>()
之类的东西,而我应该使用 An<type&>()
来代替。
所以,根据我上面的例子,正确的行是:
EXPECT_CALL(mock, myMethod(An<QVariant&>(), _)).WillOnce(Return(true));