谷歌模拟!我的测试出错。 on call 将默认 return 调用
Googlemock! Error with my test. on call will by default return invoke
我正在用 google 测试和 google 模拟编写测试。我只是重构了代码以使其可测试。我将 Client 对象从 main 传递到此代码。这样,当 main 是 运行 时,客户端对象可以是真实的,而当测试是 运行 时,客户端对象可以是假的。我正在尝试测试 Connection class 如何使用客户端对象。我收到一个错误。提前致谢!
https://github.com/rgkirch/Hacker-HUD/blob/doesnt_work/test/myConcreteConnectionTest.cpp
myConcreteConnectionTest.cpp 的内容
40e2a3063be74cc42703dfa1fc09ec37c198d530
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "myClient.hpp"
#include "myConcreteConnection.hpp"
using ::testing::A;
using ::testing::AtLeast;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Matcher;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::_;
class MockMyClient: public MyClient {
public:
MOCK_METHOD2(connect, int(uint16_t port, const char *host));
MOCK_METHOD1(print, size_t(const char[]));
MOCK_METHOD0(connected, uint8_t());
MOCK_METHOD0(read, int());
MOCK_METHOD0(stop, void());
};
TEST(downloadData, basic) {
int port = 80;
const char *host = "api.coindesk.com";
const char *path = "v1/bpi/currentprice.json";
MockMyClient client; // connection happens through client
MyConcreteConnection connection(&client, host, path); // connection prints text to client and reads from client
std::string str = makeGetRequest(host, path); // the text that connection will print to client
std::string json = "one two three {four five six}";
EXPECT_CALL(client, print(Matcher<const char*>(StrEq(str.c_str())))).Times(1); // the client's print should be called with str
ON_CALL(client, read()).WillByDefault(Return(InvokeWithoutArgs([&json]()->int { // when the connection calls the clients read, it should
static auto it = json.begin();
return (int)(*(it++)); // return the text in json
})));
std::string data = connection.read();
}
TEST(sanity, one) {
ASSERT_EQ(1,1);
}
myClient.hpp
的内容
#ifndef PROJECT_WIFICLIENTADAPTER_HPP
#define PROJECT_WIFICLIENTADAPTER_HPP
#include <cstddef>
#include <cstdint>
class MyClient {
public:
virtual int connect(uint16_t port, const char *host) =0;
virtual size_t print(const char[]) =0;
virtual uint8_t connected() =0;
virtual int read() =0;
virtual void stop() =0;
};
#endif //PROJECT_WIFICLIENTADAPTER_HPP
myConcreteConnection.hpp
的内容
#ifndef MYCONNECTION_HPP
#define MYCONNECTION_HPP
#include <string>
#include "myConnection.hpp"
#include "myClient.hpp"
#include "makeGetRequest.hpp"
#include "globals.hpp"
class MyConcreteConnection : MyConnection {
public:
MyConcreteConnection(MyConcreteConnection& connection) : client(connection.client), port(connection.port), host(connection.host), path(connection.path) {};
MyConcreteConnection(MyClient* c, const char *h, const char *p) : client(c), host(h), path(p) {
client->print(makeGetRequest(host.c_str(), path.c_str()).c_str());
};
~MyConcreteConnection() {
client->stop();
};
size_t print(const char *cs) override { return client->print(cs); };
std::string read() override {
std::string data;
for(int read = 0; (read = client->read()) > -1; data.push_back(static_cast<char>(read)));
auto i = data.find('{');
if (i == data.npos) {
i = 0;
}
return data.substr(i);
};
private:
MyClient *client;
uint16_t port;
std::string host;
std::string path;
};
#endif //MYCONNECTION_HPP
错误信息
/home/richie/Downloads/JetBrains/clion-2017.1.2/bin/cmake/bin/cmake --build /home/richie/Documents/rgkirch/Hacker-HUD/cmake-build-debug --target hhTest -- -j 4
-- Configuring done
-- Generating done
-- Build files have been written to: /home/richie/Documents/rgkirch/Hacker-HUD/cmake-build-debug
Scanning dependencies of target gtest
Scanning dependencies of target gmock
[ 8%] Building CXX object test/googletest/googlemock/gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
[ 16%] Building CXX object test/googletest/googlemock/CMakeFiles/gmock.dir/__/googletest/src/gtest-all.cc.o
[ 25%] Building CXX object test/googletest/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o
[ 33%] Linking CXX static library libgmock.a
[ 41%] Linking CXX static library libgtest.a
/usr/bin/ar qc libgtest.a CMakeFiles/gtest.dir/src/gtest-all.cc.o
/usr/bin/ar qc libgmock.a CMakeFiles/gmock.dir/__/googletest/src/gtest-all.cc.o CMakeFiles/gmock.dir/src/gmock-all.cc.o
/usr/bin/ranlib libgtest.a
/usr/bin/ranlib libgmock.a
[ 41%] Built target gmock
[ 41%] Built target gtest
Scanning dependencies of target gtest_main
[ 50%] Building CXX object test/googletest/googlemock/gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
[ 58%] Linking CXX static library libgtest_main.a
/usr/bin/ar qc libgtest_main.a CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
/usr/bin/ranlib libgtest_main.a
[ 58%] Built target gtest_main
Scanning dependencies of target hhTest
[ 66%] Building CXX object test/CMakeFiles/hhTest.dir/makeGetRequestTest.cpp.o
[ 75%] Building CXX object test/CMakeFiles/hhTest.dir/myConcreteConnectionTest.cpp.o
[ 83%] Building CXX object test/CMakeFiles/hhTest.dir/displayTest.cpp.o
[ 91%] Building CXX object test/CMakeFiles/hhTest.dir/__/pio/src/makeGetRequest.cpp.o
In file included from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock.h:58:0,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:2:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h: In instantiation of ‘testing::internal::ReturnAction<R>::Impl<R_, F>::Impl(const testing::internal::linked_ptr<T>&) [with R_ = testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >; F = int(); R = testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >]’:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h:557:44: required from ‘testing::internal::ReturnAction<R>::operator testing::Action<Func>() const [with F = int(); R = testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >]’
/home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:38:8: required from here
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h:577:39: error: no matching function for call to ‘ImplicitCast_(testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >&)’
value_(ImplicitCast_<Result>(value_before_cast_)) {}
^
In file included from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/internal/gtest-internal.h:40:0,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/gtest.h:58,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:1:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/internal/gtest-port.h:1377:11: note: candidate: template<class To> To testing::internal::ImplicitCast_(To)
inline To ImplicitCast_(To x) { return x; }
^
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/internal/gtest-port.h:1377:11: note: template argument deduction/substitution failed:
In file included from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock.h:58:0,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:2:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h:577:39: note: cannot convert ‘((testing::internal::ReturnAction<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > > >::Impl<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >, int()>*)this)->testing::internal::ReturnAction<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > > >::Impl<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >, int()>::value_before_cast_’ (type ‘testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >’) to type ‘int’
value_(ImplicitCast_<Result>(value_before_cast_)) {}
^
test/CMakeFiles/hhTest.dir/build.make:137: recipe for target 'test/CMakeFiles/hhTest.dir/myConcreteConnectionTest.cpp.o' failed
make[3]: *** [test/CMakeFiles/hhTest.dir/myConcreteConnectionTest.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:456: recipe for target 'test/CMakeFiles/hhTest.dir/all' failed
make[2]: *** [test/CMakeFiles/hhTest.dir/all] Error 2
CMakeFiles/Makefile2:468: recipe for target 'test/CMakeFiles/hhTest.dir/rule' failed
make[1]: *** [test/CMakeFiles/hhTest.dir/rule] Error 2
Makefile:279: recipe for target 'hhTest' failed
make: *** [hhTest] Error 2
它在我删除 Return()
后构建。
现在是
ON_CALL(client, read()).WillByDefault(InvokeWithoutArgs([&json]()->int { // when the connection calls the clients read, it should
static auto it = json.begin();
return (int)(*(it++)); // return the text in json
}));
我正在用 google 测试和 google 模拟编写测试。我只是重构了代码以使其可测试。我将 Client 对象从 main 传递到此代码。这样,当 main 是 运行 时,客户端对象可以是真实的,而当测试是 运行 时,客户端对象可以是假的。我正在尝试测试 Connection class 如何使用客户端对象。我收到一个错误。提前致谢!
https://github.com/rgkirch/Hacker-HUD/blob/doesnt_work/test/myConcreteConnectionTest.cpp
myConcreteConnectionTest.cpp 的内容
40e2a3063be74cc42703dfa1fc09ec37c198d530
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "myClient.hpp"
#include "myConcreteConnection.hpp"
using ::testing::A;
using ::testing::AtLeast;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Matcher;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::_;
class MockMyClient: public MyClient {
public:
MOCK_METHOD2(connect, int(uint16_t port, const char *host));
MOCK_METHOD1(print, size_t(const char[]));
MOCK_METHOD0(connected, uint8_t());
MOCK_METHOD0(read, int());
MOCK_METHOD0(stop, void());
};
TEST(downloadData, basic) {
int port = 80;
const char *host = "api.coindesk.com";
const char *path = "v1/bpi/currentprice.json";
MockMyClient client; // connection happens through client
MyConcreteConnection connection(&client, host, path); // connection prints text to client and reads from client
std::string str = makeGetRequest(host, path); // the text that connection will print to client
std::string json = "one two three {four five six}";
EXPECT_CALL(client, print(Matcher<const char*>(StrEq(str.c_str())))).Times(1); // the client's print should be called with str
ON_CALL(client, read()).WillByDefault(Return(InvokeWithoutArgs([&json]()->int { // when the connection calls the clients read, it should
static auto it = json.begin();
return (int)(*(it++)); // return the text in json
})));
std::string data = connection.read();
}
TEST(sanity, one) {
ASSERT_EQ(1,1);
}
myClient.hpp
的内容#ifndef PROJECT_WIFICLIENTADAPTER_HPP
#define PROJECT_WIFICLIENTADAPTER_HPP
#include <cstddef>
#include <cstdint>
class MyClient {
public:
virtual int connect(uint16_t port, const char *host) =0;
virtual size_t print(const char[]) =0;
virtual uint8_t connected() =0;
virtual int read() =0;
virtual void stop() =0;
};
#endif //PROJECT_WIFICLIENTADAPTER_HPP
myConcreteConnection.hpp
的内容#ifndef MYCONNECTION_HPP
#define MYCONNECTION_HPP
#include <string>
#include "myConnection.hpp"
#include "myClient.hpp"
#include "makeGetRequest.hpp"
#include "globals.hpp"
class MyConcreteConnection : MyConnection {
public:
MyConcreteConnection(MyConcreteConnection& connection) : client(connection.client), port(connection.port), host(connection.host), path(connection.path) {};
MyConcreteConnection(MyClient* c, const char *h, const char *p) : client(c), host(h), path(p) {
client->print(makeGetRequest(host.c_str(), path.c_str()).c_str());
};
~MyConcreteConnection() {
client->stop();
};
size_t print(const char *cs) override { return client->print(cs); };
std::string read() override {
std::string data;
for(int read = 0; (read = client->read()) > -1; data.push_back(static_cast<char>(read)));
auto i = data.find('{');
if (i == data.npos) {
i = 0;
}
return data.substr(i);
};
private:
MyClient *client;
uint16_t port;
std::string host;
std::string path;
};
#endif //MYCONNECTION_HPP
错误信息
/home/richie/Downloads/JetBrains/clion-2017.1.2/bin/cmake/bin/cmake --build /home/richie/Documents/rgkirch/Hacker-HUD/cmake-build-debug --target hhTest -- -j 4
-- Configuring done
-- Generating done
-- Build files have been written to: /home/richie/Documents/rgkirch/Hacker-HUD/cmake-build-debug
Scanning dependencies of target gtest
Scanning dependencies of target gmock
[ 8%] Building CXX object test/googletest/googlemock/gtest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
[ 16%] Building CXX object test/googletest/googlemock/CMakeFiles/gmock.dir/__/googletest/src/gtest-all.cc.o
[ 25%] Building CXX object test/googletest/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o
[ 33%] Linking CXX static library libgmock.a
[ 41%] Linking CXX static library libgtest.a
/usr/bin/ar qc libgtest.a CMakeFiles/gtest.dir/src/gtest-all.cc.o
/usr/bin/ar qc libgmock.a CMakeFiles/gmock.dir/__/googletest/src/gtest-all.cc.o CMakeFiles/gmock.dir/src/gmock-all.cc.o
/usr/bin/ranlib libgtest.a
/usr/bin/ranlib libgmock.a
[ 41%] Built target gmock
[ 41%] Built target gtest
Scanning dependencies of target gtest_main
[ 50%] Building CXX object test/googletest/googlemock/gtest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
[ 58%] Linking CXX static library libgtest_main.a
/usr/bin/ar qc libgtest_main.a CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
/usr/bin/ranlib libgtest_main.a
[ 58%] Built target gtest_main
Scanning dependencies of target hhTest
[ 66%] Building CXX object test/CMakeFiles/hhTest.dir/makeGetRequestTest.cpp.o
[ 75%] Building CXX object test/CMakeFiles/hhTest.dir/myConcreteConnectionTest.cpp.o
[ 83%] Building CXX object test/CMakeFiles/hhTest.dir/displayTest.cpp.o
[ 91%] Building CXX object test/CMakeFiles/hhTest.dir/__/pio/src/makeGetRequest.cpp.o
In file included from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock.h:58:0,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:2:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h: In instantiation of ‘testing::internal::ReturnAction<R>::Impl<R_, F>::Impl(const testing::internal::linked_ptr<T>&) [with R_ = testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >; F = int(); R = testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >]’:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h:557:44: required from ‘testing::internal::ReturnAction<R>::operator testing::Action<Func>() const [with F = int(); R = testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >]’
/home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:38:8: required from here
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h:577:39: error: no matching function for call to ‘ImplicitCast_(testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >&)’
value_(ImplicitCast_<Result>(value_before_cast_)) {}
^
In file included from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/internal/gtest-internal.h:40:0,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/gtest.h:58,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:1:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/internal/gtest-port.h:1377:11: note: candidate: template<class To> To testing::internal::ImplicitCast_(To)
inline To ImplicitCast_(To x) { return x; }
^
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googletest/include/gtest/internal/gtest-port.h:1377:11: note: template argument deduction/substitution failed:
In file included from /home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock.h:58:0,
from /home/richie/Documents/rgkirch/Hacker-HUD/test/myConcreteConnectionTest.cpp:2:
/home/richie/Documents/rgkirch/Hacker-HUD/test/googletest/googlemock/include/gmock/gmock-actions.h:577:39: note: cannot convert ‘((testing::internal::ReturnAction<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > > >::Impl<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >, int()>*)this)->testing::internal::ReturnAction<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > > >::Impl<testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >, int()>::value_before_cast_’ (type ‘testing::PolymorphicAction<testing::internal::InvokeWithoutArgsAction<downloadData_basic_Test::TestBody()::<lambda()> > >’) to type ‘int’
value_(ImplicitCast_<Result>(value_before_cast_)) {}
^
test/CMakeFiles/hhTest.dir/build.make:137: recipe for target 'test/CMakeFiles/hhTest.dir/myConcreteConnectionTest.cpp.o' failed
make[3]: *** [test/CMakeFiles/hhTest.dir/myConcreteConnectionTest.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:456: recipe for target 'test/CMakeFiles/hhTest.dir/all' failed
make[2]: *** [test/CMakeFiles/hhTest.dir/all] Error 2
CMakeFiles/Makefile2:468: recipe for target 'test/CMakeFiles/hhTest.dir/rule' failed
make[1]: *** [test/CMakeFiles/hhTest.dir/rule] Error 2
Makefile:279: recipe for target 'hhTest' failed
make: *** [hhTest] Error 2
它在我删除 Return()
后构建。
现在是
ON_CALL(client, read()).WillByDefault(InvokeWithoutArgs([&json]()->int { // when the connection calls the clients read, it should
static auto it = json.begin();
return (int)(*(it++)); // return the text in json
}));