Design for following situation having gtest procedure - c++

In my current implementation i have 2 files (i am stuck and not getting any further)
//firstFile.cpp
class first
{
//some object of xyz class
};
first f; //global
TEST(Suite, Testcase
{
//do something
}
//secondFile.cpp
class second
{
public:
//some data members
void function()
}
Task :- I want to call TEST (consider it a special function, when it is called, object of first (i.e. global object defined will be created). In test i want to save some data for latter processing, which obviously i can't do in first class as it will be initialized on every TEST call.
Problem :- I though of having a separate class (in another .cpp file) which have required data structure to be saved. I want a way to access those data structure in TEST procedure and keep on adding the data over previous data with every TEST call. I can't have an object for second class in firstFile.cpp as it will also be created/destroyed on every call.
Any suggestion? Also i can't do anything about TEST procdedure, this is the way it is.

In gtest you can define test fixtures. It's a bit like defining a context for a set of tests. It gives you means to SetUp/TearDown stuff before/after each of your tests, but also before/after your test suite runs. Note that SetUp and TearDown are case sensitive.
struct MyFixture : testing::Test
{
private:
// stuff
protected:
//! Called before running all tests
static void SetUpTestCase();
//! Called after running all tests
static void TearDownTestCase();
//! Called before each test
void SetUp() {}
//! Called after each test
void TearDown() {}
public:
static SomeSharedObject& GetSharedObjInTest() {}
};
and in the test case you would need to call
TEST_F(MyFixture, MyTest_Name)
{
// some cool stuff here
}
You could simply create a static instance of first inside that fixture, initialize it inside SetUp() and use a static getter to access it from inside your different tests.
refer to the documentation gtest - Sharing resources between tests in the same test case

Related

How to set expectation on a mocked method which is called inside another mocked method C++

I am a beginner with google testing framework and have looked up for the solution to this question on SO, but could not find any solutions with respect to C++. Anyway here is what i am trying to do. I have a state machine(service) which is called inside a client code.
//IStateMachine.h
class IStateMachine
{
public:
bool Run(const std::string& action) = 0;
bool IsTxnValid(const std::string& action)= 0;
}
//StateMachine.h
class StateMachine : public IStateMachine
{
bool Run(const std::string& action) override;
bool IsTxnValid(const std::string& action) override;
}
//StateMachine.cpp
bool StateMachine::IsTxnValid(const std::string& action)
{
//Checks whether the given action is valid for the given state.
}
bool StateMachine::Run(const std::string& action)
{
if(IsTxnValid(action)) // #E
{
//Do processing
return true;
}
return false;
}
//Client.h contains a class Client which has function called RunService.
Client
{
public:
void RunService();
std::unique_ptr<IStateMachine> service_; // Initialised to a non null value in either ctr or
// factory.
}
//Client.cpp
bool Client::RunService(std::string&action)
{
if(!service_->Run(action)) //Run in turn calls IsTxnValid().
{
return false;
}
return true;
}
Now i am writing a test case to test the functioning of RunService. I am expecting that if Client::IsTxnValid(param) returns false, then so should RunService.
I have successfully set up the testing recipe and could get the basic tests running. Here is the relevant test i have written. On running this test the i get the error, that IsTransitionValid is never called.
TEST_F(ClientTest, RunService)
{
EXPECT_CALL(*p_service, Run("some_action")); // #A
// EXPECT_CALL(*p_service, Run(testing::_)).WillOnce(::testing::Return(true)); //#B
EXPECT_CALL(*p_service,IsTransitionValid(testing::_)).WillOnce(::testing::Return(false)); //#C : This never gets called.
EXPECT_EQ(false, x_client->RunService());
}
How do i correctly call IsTransitionValid ?
You don't need to set this expectation. I'd go even further: you should not even depend on the implementation of Run in IStateMachine: you should only care about what input it is provided with (parameters, checked with matchers) and what output it can return (so basically only the contract between these two classes) and that's the beauty of it!
It is an implementation detail of StateMachine class (the real implementation) what is done when Run is called. The only thing you need to check in your test is to act upon the result of Run. Using triple A rule (arrange, act, assert): you arrange the test case conditions (using EXPECT_CALLs), then you act (calling RunService) and then you assert (checking the result of RunService).
The technical details:
When you create a mock by inheriting from class Foo:
class Foo {
public:
virtual ~Foo() = default;
virtual void bar() = 0;
}
By defining:
class FooMock : public Foo {
MOCK_METHOD0( bar, void());
}
gmock will add bar (the method to override) and gmock_bar (internal detail of gmock) methods to FooMock class. bar has empty implementation in this case. FooImpl and FooMock share the interface, but have different implementations - hence no call to IsTxnValid is made in Run: the mock class just doesn't know (nor care) how Run is implemented in StateMachine. Remember: in your testcase you interact with StateMachineMock and you only care about the interaction with its public interface, the contract between these two classes and how they cooperate together.
That being said, you of course need to utest the StateMachine class. It may depend on yet another interfaces in its implementations: that will be tested with different set of mocks. But Client should not know about this.

gmock Multiple mock instances, but only one is effective

I would like to test a class (Controller) that manages a set of entities of a certain kind. Entities are created internally in this class because a factory would be an overkill here, so here is how I inject mocks into it:
class TestController : public Controller {
public:
/* Mechanism for a mock injection */
std::shared_ptr<IEntity> create_entity() override {
return temp_entity;
}
/* Variable to hold the entity being injected */
std::shared_ptr<IEntity> temp_entity;
};
Production code invokes create_entity() in the Controller class, which I overload here, and adds the result to a container. temp_entity is the way I supply my mocks and the test, where I supply two distinct mock instances, looks like this:
class MockEntity : public IEntity {
MOCK_METHOD0(perform_operation, bool());
}
TEST(ControllerTest, TestFailure) {
std::shared_ptr<TestController> controller = std::make_shared<TestController>();
std::shared_ptr<MockEntity> entity1 = std::make_shared<MockEntity>();
controller->temp_entity = entity1;
controller->add_entity(); // This invokation fetches the result of create_entity()
std::shared_ptr<MockEntity> entity2 = std::make_shared<MockEntity>();
controller->temp_entity = entity2;
controller->add_entity(); // This invokation fetches the result of create_entity()
EXPECT_CALL(*entity1, perform_operation().WillOnce(::testing::Return(true));
EXPECT_CALL(*entity2, perform_operation().WillOnce(::testing::Return(false));
controller->run();
}
controller.run() only concurrently executes perform_operation() on each of the entities.
When the test is run, the function in the second expectation is called twice and the function in the first expectation is not run at all. I am sure that the controller operates on two distinct versions of an entity before executing run() function.
Is there a fundamental problem in what I am trying to do? How can I separate my expectations for these two mocks in a test? I tried creating two distinct mock classes with perform_operation() method being implemented in the mock body and when running the test in the debugger I still hit the method of one mock class twice.
The test looks correct and the way, how you inject the mocks into the system under test, is an absolutely reasonable method.
I suppose, the critical issue is in your class under Test. I rebuild your Test with the following controller:
class Controller {
public:
virtual std::shared_ptr<IEntity> create_entity() = 0;
void add_entity() {
auto entity = create_entity();
entities.push_back(entity);
}
void run() {
for(auto e : entities) {
bool i = e->perform_operation();
}
}
std::vector<std::shared_ptr<IEntity> > entities;
};
With this class the test succeeded like expected.

How can i decorate Google Test fixture

I have some test:
class Somefixture: ::testing::Test{};
class Somefixture2: ::testing::Test{};
TEST_F(SomeFixture, SomeName)
{
// ...
}
How can i automatically link test to both fixtures (decorate)?
TEST_F2(SomeFixture, SomeFixture2, SomeName){}
While the required result will be as if I wrote:
TEST_F(SomeFixture, SomeName)
{
// ...
}
TEST_F(SomeFixture2, SomeName)
{
// ...
}
Without the unnecessary code duplication
With one little exception (two tests can't have the same name), this should go in the right derection:
#define TEST_F2(F1, F2, Name) \
template <struct Fixture> struct MyTester##Name : Fixture { \
void test##Name(); \
}; \
\
TEST_F(MyTester##Name<F1>, Name##1){ test##Name(); } \
TEST_F(MyTester##Name<F2>, Name##2){ test##Name(); } \
\
template <struct Fixture> void MyTester##Name::test##Name()
This will call two tests, each using MyTester as fixture that inherits from one of the two fixtures. Since do_test is a member of MyTester, it has access to all inherited members from the fixtures. The test framework will create an MyTester object for each test and the corresponding actual fixture will get created as base class object. To avoid naming conflicts with other tests or bewteen different calls of TEST_F2, I appended the Name to the template name and test method name. The TEST_F macro calls are supplied with a name and an index. I did not test it, since I don't have Google Test, but the mechanisms in many of those testing frameworks work similar.
How can i automatically link test to both fixtures (decorate)?
By adding a common base class :
class CommonFixture
{
public:
// add member variables and initialize them in the constructor
};
class Somefixture1 : ::testing::Test, protected CommonFixture{}
class Somefixture2 : ::testing::Test, protected CommonFixture{}
Tests stay the same :
TEST_F(SomeFixture1, SomeName)
{
// ...
}
TEST_F(SomeFixture2, SomeName)
{
// ...
}
Now you got a common fixture for Somefixture1 and Somefixture2. You can access these common objects from within your tests.
You can go with BЈовић approach which seems good.
Or anther approach which required a small change to the test itself can be having a "super" class which will have both instances as members.
class superFuxture
{
public:
Somefixture1 f1;
Somefixture2 f2;
}
Then you test will be like that:
TEST_F(superFuxture, SomeName)
{
//when you were accessing a member of Somefixture1 you'll now need to do:
//f1.SomeFixture1Member
}
Google Test has two ways of executing the same test body in different contexts: value-parameterized tests or typed/type-parameterized tests. Not precisely what you want but it's the closest thing it offers.

Mocking a method using Mockito

Does mocking a method using mockito ensures that mocked method will never be called? I have Main class which contains some code i want to write unit tests for and i have one unit test class MainTest which contains unit tests for Main class.
eg:
Source Class:
package abc;
public class Main {
public int check1() {
int num = 10;
num = modify(num);
return num;
}
public int modify(int num) {
if (num % 10 == 0) return num / 10;
return -1;
}
}
Junit Test (using mockito)
package abc;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
public class MainTest {
private static Main main;
#BeforeClass
public static void setUp() {
main = Mockito.mock(Main.class);
Mockito.when(main.modify(10)).thenReturn(5);
}
#Test
public void testCheck1() {
Test1 main1 = new Main();
int num = main.check1();
Assert.assertEquals(5, num);
}
}
This test is failing. Why?
EDITED
Because you didn't provide a behavior for check1(). ALL methods get mocked, so without you providing a behavior, check1() returns a default value for the return type of int, which is 0. Furthermore, check1() since it is mocked does not even get to call modify().
If you are trying to test a class, you never mock the Class Under Test. On rare occasion, you might have to Spy a class under test. Rather, you mock collaborators only.
I am guessing your example was a contrived one (I hope). But if you are writing and testing a class where you think you want to modify some internal method's behavior, I see two likely probabilities:
You may need to refactor the functionality of the method you want to mock-out into a collaborator class. Then it makes sense to go ahead and mock that behavior as a collaborator.
You may also may need to modify the API so that you can pass in what is going to change. In your case, check1() hard-codes the value it passes to modify(), which is why you are trying to mock modify(). If instead that value were a parameter to check1() or a settable field in class Main, then there wouldn't even be a need to use a mock at all.
The Problem with your Test is, that you do not use your newly created main1 object.
If you want to change the behaviour of your systen under test (SUT) you would normally do something like this:
#Test
public void testCheck1() {
Test1 main1 = new Main(){
public int modify(int num) {
return 5; // hard coded return value
}
};
int num = main1.check1();
Assert.assertEquals(5, num);
}
This creates a subclass of Main with a new implementation of the modify-method.
This is an important technique for replacing hard-to-test methods in your SUT. You would normally use it to avoid expensive remote calls or similar.
It is of course possible to use a Mockito spy like this:
#Test
public void testCheck1() {
Test1 main1 = spy(new Main());
stub(main1.modify(10)).toReturn(5);
int num = main1.check1();
Assert.assertEquals(5, num);
}
Though i am late,it might be useful to some one. Just to add to #VivaceVivo answer: when using spies please consider doReturn|Answer|Throw() family of methods for stubbing. Sometimes it's impossible or impractical to use when(Object) for stubbing spies. more info here

How to mock a method which also belongs to the target class itself?

Let's say we are testing a class C which has 2 methods M1 and M2 where M1 calls M2 when executed.
Testing M2 is ok, but how can we test M1? The difficulty is that we need to mock M2 if I'm not misunderstanding things.
If so, how can we mock another method while testing a method defined in the same class?
[Edit]
Class C has no base classes.
You can do this by setting the CallBase property on the mock to true.
For example, if I have this class:
public class Foo
{
public virtual string MethodA()
{
return "A";
}
public virtual string MethodB()
{
return MethodA() + "B";
}
}
I can setup MethodA and call MethodB:
[Fact]
public void RunTest()
{
Mock<Foo> mockFoo = new Mock<Foo>();
mockFoo.Setup(x => x.MethodA()).Returns("Mock");
mockFoo.CallBase = true;
string result = mockFoo.Object.MethodB();
Assert.Equal("MockB", result);
}
You should let the call to M1 pass through to a real instance of the M2 method.
In general, you should be testing the black box behaviour of your classes. Your tests shouldn't care that M1 happens to call M2 - this is an implementation detail.
This isn't the same as mocking external dependencies (which you should do)...
For example, say I have a class like this:
class AccountMerger
{
public AccountMerger(IAccountDao dao)
{
this.dao = dao;
}
public void Merge(Account first, Account second, MergeStrategy strategy)
{
// merge logic goes here...
// [...]
dao.Save(first);
dao.Save(second);
}
public void Merge(Account first, Account second)
{
Merge(first, second, MergeStrategy.Default);
}
private readonly IAccountDao dao;
}
I want my tests to show that:
Calling Merge(first, second, strategy) results in two accounts getting saved that have been merged using the supplied rule.
Calling Merge(first, second) results in two accounts getting saved that have been merged using the default rule.
Note that both of these requirements are phrased in terms of inputs and effects - in particular, I don't care how the class achieves these results, as long as it does.
The fact that the second method happens to use the first isn't something I care about, or even that I want to enforce - if I do so, I'll write very brittle tests. (There's even an argument that if you've messed about with the object under test using a mocking framework, you're not even testing the original object any more, so what are you testing?) This is an internal dependency that could quite happily change without breaking the requirements:
// ...
// refactored AccountMerger methods
// these still work, and still fulfil the two requirements above
public void Merge(Account first, Account second, MergeStrategy strategy)
{
MergeAndSave(first, second, strategy ?? MergeStrategy.Default);
}
public void Merge(Account first, Account second)
{
// note this no longer calls the other Merge() method
MergeAndSave(first, second, MergeStrategy.Default);
}
private void MergeAndSave(Account first, Account second, MergeStrategy strategy)
{
// merge logic goes here...
// [...]
dao.Save(first);
dao.Save(second);
}
// ...
As long as my tests only check inputs and effects, I can easily make this kind of refactoring - my tests will even help me to do so, as they make sure I haven't broken the class while making changes.
On the other hand, I do about the AccountMerger using the IAccountDao to save accounts following a merge (although the AccountMerger shouldn't care about the implementation of the DAO, only that it has a Save() method.) This DAO is a prime candidate for mocking - an external dependency of the AccountMerger class, feeling an effect I want to check for certain inputs.
You shouldn't mock methods in the target class, you should only mock external dependencies.
If it seems to make sense to mock M2 while testing M1 it often means that your class is doing too many things. Consider splitting the class and keeping M2 in one class and move M1 to a higher level class, which would use the class containing M2. Then mocking M2 is easy, and your code will actually become better.