How do I mock this on C++? - c++

FuncRes Test::test(HttpRequest& request, std::string& result) {
try {
auto httpClientSync = HttpClientSync::create(param);
HttpResponse response = httpClientSync->execute(request);
if (...) {
return FuncRes::SUCCESS;
} else if (...) {
return FuncRes::RETRY;
} else {
return FuncRes::FAILED;
}
} catch (...) {
return FuncRes::RETRY;
} catch (...) {
return FuncRes::FAILED;
}
}
httpClientSync is a local variable, it will destroy when the test is done.
I'm confused if I can mock HttpClientSync and "execute" method?

Refactor this function into 2 parts, one that creates real HttpClientSync, and one that accepts HttpClientSync interface:
FuncRes Test::test(HttpClientSync& httpClientSync, HttpRequest& request, std::string& result);
FuncRes Test::test(HttpRequest& request, std::string& result) {
auto httpClientSync = HttpClientSync::create(param);
test(httpClientSync, request, result);
}
Then test variant which accepts HttpClientSync in arguments, and pass mock instead of real client.
If you need to test some other code which calls this test function, and you still want to mock HttpClientSync, then instead of storing param in your Test class, store HttpClientSync& client instance, and pass it in constructor.

Related

How to return a specific value every nth time of a consecutive call with Gmock

In the code Google Mock test snippet there is an EXPECT_CALL that returns True and an argument reference for 200 times.
How can I let the test only return True every nth time. For example return True each 10th call and otherwise return False.
class MockHandler : public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
}
TEST(TestDispatcher, HandlePing)
{
auto mockedHandler = make_unique<MockHandler>();
Msg rxMsg = { REQUEST::REQ_PING, sizeof(DefaultMsg_t), rxMsg.rx,(uint8_t*)"0"};
EXPECT_CALL(*mockedHandler,
RxMsg(_)).Times(checkValue).WillRepeatedly(
DoAll(SetArgReferee<0>(rxMsg), Return(TRUE)));
Dispatcher dispatcher(10, mockedHandler);
for (int i = 0; i < 199; i++)
{
dispatcher.RunToCompletion();
}
}
There are few approaches that might work for you. I like the solution with Invoke as a default action, because it is the most flexible. You didn't provide mcve in your question, so I wrote very simple implementations for the classes you use. Also you made a mistake using unique_ptr for the mock. In 99% of cases is must be shared_ptr, because you are sharing it between testing environment and your System Under Test.
class Msg {};
class Handler {
public:
virtual bool RxMsg(Msg &msg) = 0;
};
class MockHandler: public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
};
class Dispatcher {
public:
Dispatcher(std::shared_ptr<Handler> handler): h_(handler) {}
void run() {
Msg m;
std::cout << h_->RxMsg(m) << std::endl;
}
private:
std::shared_ptr<Handler> h_;
};
class MyFixture: public ::testing::Test {
protected:
MyFixture(): mockCallCounter_(0) {
mockHandler_.reset(new MockHandler);
sut_.reset(new Dispatcher(mockHandler_));
}
void configureMock(int period) {
ON_CALL(*mockHandler_, RxMsg(_)).WillByDefault(Invoke(
[this, period](Msg &msg) {
// you can also set the output arg here
// msg = something;
if ((mockCallCounter_++ % period) == 0) {
return true;
}
return false;
}));
}
int mockCallCounter_;
std::shared_ptr<MockHandler> mockHandler_;
std::unique_ptr<Dispatcher> sut_;
};
TEST_F(MyFixture, HandlePing) {
configureMock(10);
for (int i = 0; i < 199; i++) {
sut_->run();
}
}
At the beginning of each test you should call configureMock method that will Invoke ON_CALL macro setting the default action for your mock. Function passed to Invoke can be any function matching the signature of the method you are overwriting. In this case it;s a function that counts how many times mock has already been called and returns appropriate value. You can also assign some particular object to the msg output argument.

Argument capturing on the insides of closures in Spock

I am trying to test a method that does an invocation with a closure, something like this:
def foo(Long param) {
AnObject.doSomething {
bar(param)
}
}
And I want to test that doSomething is called with a closure that calls bar with the expected value inside.
I'm able to test properly the doSomething invocation by creating a spy and doing
when:
service.foo(1L)
then:
1 * AnObject.doSomething{_}
However, I cannot seem to find a way to perform assertions on the contents of the closure.
What's the appropriate way to assert that inside the closure bar gets called with 1L?
Without seeing more of your code, I think you would need to spy on the class providing the bar method. This is a bit contrived because the test is supplying the closure, but I think it is something like this:
import spock.lang.Specification
class Bar {
void bar(def param) {
println param
}
}
class DoSomethingTestSpec extends Specification {
class AnObject {
void doSomething(Closure c) {
def param = 1L
c.call(param)
}
}
def "test AnObject doSomething calls the closure"() {
given:
def closure = { def p ->
Bar.bar(p)
}
and:
GroovySpy(Bar, global:true)
and:
AnObject anObject = new AnObject()
when:
anObject.doSomething(closure)
then:
1 * Bar.bar(_) >> { args ->
assert args[0] == 1L
}
}
}

Mocking Java 8 lamba function with Mockito 2

I am using JDBI 3 and have written the following utility function.
public class JdbiHelper {
// ...
public <T, DAO> T fetch(final Function<DAO, T> function, Class<DAO> daoClass) {
return dbi.withHandle(handle -> {
final DAO dao = handle.attach(daoClass);
try {
return function.apply(dao);
}
finally {
handle.close();
}
});
}
}
which I can call in methods like this
public Optional<Account> findByEmailAddress(final String emailAddress) {
if (!exists(emailAddress))
return Optional.empty();
return jdbiHelper.fetch(dao -> ofNullable(dao.selectByEmailAddress(emailAddress)), AccountDAO.class);
}
private boolean exists(final String emailAddress) {
return jdbiHelper.fetch(dao -> dao.count(emailAddress) > 0, AccountDAO.class);
}
I am trying to write a test for the findByEmailAddress mocking jdbiHelper using Mockito 2 but cannot work out how to mock the dao -> part of the method.
I've tried using jdbiHelper.fetch(any(Function.class), eq(AccountDAO.class)) but as there are two different expectations of what to return it fails trying to cast one or the other.
Passing in a mocked Function causes a NPE as the dao param is null.

GoogleMock: How to SetArgReferee according to another input parameter?

I would like to use GoogleMock to mock a service as below:
class Request
{
int req_id;
int request;
};
class Response
{
int req_id;
int response;
};
int request(Response& res, const Request& req)
{
res.req_id = req.req_id;
res.response = 2 * req.request;
return 1;
}
EXPECT_CALL(mock_service, request(_,_)).WillOnce(DoAll(SetArgReferee<0>(/* what here? */), Return(1)));
How can I SetArgReferee for the Response& res according to the passed in const Request& req, i.e. res.req_id = req.req_id; and res.response = 2 * req.request; ?
Your code does not look like something that could be mocked - but I guess this is just illustration of the problem.
So assuming that you have mocked function reqest within mocked class MockService - then use Invoke Action with your request function as parameter:
EXPECT_CALL(mock_service, request(_,_)).WillOnce(Invoke(&request));
If you like to just call base class function - then do something like this:
class mock_service_class : public service_class
{
public:
MOCK_METHOD2(request, int(Response& res, const Request& req));
int baseRequest(Response& res, const Request& req)
{
return service_class::request(res, req);
}
};
And do your EXPECT_CALL in this way:
EXPECT_CALL(mock_service, request(_,_))
.WillOnce(Invoke(&mock_servide,
&mock_service_class::baseRequest));

How to mock a method which passes in clazz?

I'm trying to write a unit test for a method which has takes in a .class parameter.
For example:
ExampleService {
def myExample(clazz){
//do stuff and return some object
}
}
/* How the above function gets used */
AnotherExampleService extends exampleService {
def blah() {
def obj = myExample(AnotherClass.class)
}
}
/* Now I need to test the above blah() function */
AnotherExampleServiceSpec extends Specification {
def "test blah"() {
//The following doesn't seem to work
ExampleService.metaClass.myExample = { def arg1 -> obj }
}
}
I'm pretty new to Groovy/Grails, so any help would be much appreciated. I basically want to know why my unit test doesn't seem to work, and how to test such a function that takes in a paramter of a class instance.
Thank you for your help!
I would probably subclass the ExampleService in the test. So it looked like:
ExampleService {
def myExample(clazz){
//do stuff and return some object
}
}
AnotherExampleService extends ExampleService {
def exampleService
def blah() {
def obj = myExample(AnotherClass)
}
}
AnotherExampleServiceSpec extends Specification {
def "test blah"() {
given:
AnotherExampleService service = new AnotherExampleService() {
#Override
def myExample(clazz){
//whatever you want to do
return whatEverResult
}
when:
def result = service.blah (SomeClass)
then:
result
}
}
As you can see the myExample methods is overridden here to return some mock value and there's no tinkering with metaclass :-) To make it easier for Groovy you can explicitly state the input type e.g. def myExample(Class clazz).