gtest setup teardown TestEnvironment - issue with class variable - c++

I have another gtest where I do the following and it works fine:
TEST(TEST1, TestName)
{
ClassName env;
const String original = env(Con::WorkingDir);
Con c = env;
}
However, I want this to be set for another gtest class and hold throughout the entire test fixture. However, I'm getting this error message:
Call of an object of class type without appropriate operator or
conversion functions to pointer-to-function type.
I'm looking at initialize gtest, and I'm not sure what I'm missing for this. It could be use of static variables I'm not familiar with. I don't want ClassName to be static, though.
What am I doing wrong with this?
//this is intended to setup env to use in teardown.
class TestEnvironment : public ::testing::Environment {
public:
static String getEn() {
ClassName env;
static const String sString = env(Con::WorkingDir); //env has the error message here
return sString;
}
}
class UnitTest : public ::testing::Test
{
public:
virtual void SetUp() {
//
}
virtual void TearDown() {
//set env back to initial value
getEn();
//process env info;
}

class UnitTest : public ::testing::Test { //can't use Environment here because of name conflict in our code, although that was used by static const variable setup in example link.
public:
String orig;
}
class UnitTest : public ::testing::Test
{
public:
virtual void SetUp() {
orig = code;
}
virtual void TearDown() {
//process orig;
}
It turned out that even though our code was looking for a const string, we don't have to save it as const.

Related

GTest - how to prepare data for multiple usage via SetUp method?

I am trying to run some google tests, and I have quite a lot of code to repeat in each test fixture, so I want to make the code as brief as possible, and I would like to use the SetUp method of the child class of Testing::test parent class, but the TEST_F fixtures do not recognize the variables from SetUp
This is the simplest example I can come up with:
class FooTest: public testing::Test
{
protected:
virtual void SetUp() // using void SetUp() override does not help
{
int FooVar = 911;
}
virtual void TearDown()
{
}
};
TEST_F(FooTest, SampleTest)
{
// FooTest::SetUp(); // This does not help as well
EXPECT_EQ(911, FooVar);
}
When I try to compile this code it shows an error that FooVar was not declared in this scope. How can I fix it?
Thank you very much for any help.
FooVar is a local variable inside the SetUp method. If you want to use it in the test fixtures, it needs to be a class member:
class FooTest: public testing::Test
{
protected:
int FooVar;
virtual void SetUp() override
{
this.FooVar = 911;
}
};
In this example, if you are only setting integral types, should just make them const member variables.

TEST_F in google mock giving error

It's a simple example to use google mocking along with fixtures. I am trying to setup up and learn google mock on Xcode and wrote following code
using ::testing::Return;
class Shape {
public:
virtual int calculateArea() = 0;
virtual std::string getShapeColor() = 0; // this interface must have been used by some other class under test
};
// Mock class for Shape
class MockShape : public Shape{
public:
MOCK_METHOD0(calculateArea, int());
MOCK_METHOD0(getShapeColor, std::string());
};
// class under test
class Show{
public:
Show() : printFlag(false), isColorValid(false) {}
void printArea(Shape *shape) {
if (shape->calculateArea() <= 0)
printFlag = false;
else
printFlag = true;
}
void printColor(Shape *shape) {
if (shape->getShapeColor().compare("black"))
isColorValid = true;
else
isColorValid = false;
}
bool printFlag;
bool isColorValid;
};
// Test fixture for class under test
class FixtureShow : public ::testing::Test{
public:
void SetUp(){}
void TearDown(){}
void SetUpTestCase(){}
void TearDownTestCase(){}
Show show; // common resources to be used in all the test cases
MockShape mockedShape;
};
TEST_F(FixtureShow, areaValid) {
EXPECT_CALL(mockedShape, calculateArea()).WillOnce(Return(5));
show.printArea(&mockedShape);
EXPECT_EQ(show.printFlag, true);
}
"TEST_F(FixtureShow, areaValid) " is giving error "Call to non static member function without an object argument". Can anyone help me why am I getting this error?
SetUpTestCase() and TearDownTestCase() are meant to be declared as static member functions. You can also delete them unless you are planning to put some code in.

C++ Google Mock - EXPECT_CALL() - expectation not working when not called directly

I'm still pretty new to Google Mock so learning as I go. I've just been adding some unit tests and I've run into an issue where I can't get ON_CALL() to correctly stub a method called from within a method.
The following code outlines what I have;
class simpleClass
{
public:
bool simpleFn1() { return simpleFn2(); }
virtual bool simpleFn2() { return FALSE; }
}
In my unit test I have:
class simpleClassMocked : public simpleClass
{
private:
MOCK_METHOD0(simpleFn2, bool());
}
class simpleClassTests : public ::testing::Test
{
}
TEST_F(simpleClassTests, testSimpleFn2)
{
shared_ptr<simpleClassMocked> pSimpleClass = shared_ptr< simpleClassMocked >(new simpleClassMocked());
ON_CALL(*pSimpleClass, simpleF2()).WillByDefault(Return(TRUE));
// This works as expected - simpleFn2() gets stubbed
pSimpleClass->simpleFn2();
// This doesn't work as expected - when simpleFn1 calls simpleFn2 it's not the stubbed expectation???
pSimpleClass->simpleFn1();
}
I figure I must be missing something obvious here, can anyone help? Thanks!
you'll have to Mark the method as virtual and add a corresponding MOCK function in the simpleClassMocked class
class simpleClass
{
public:
virtual bool simpleFn1() { return simpleFn2(); }
virtual bool simpleFn2() { return FALSE; }
}
Also, you need to put the Mock methods in the public area
class simpleClassMocked : public simpleClass
{
public:
MOCK_METHOD0(simpleFn2, bool());
MOCK_METHOD0(simpleFn1, bool());
}
It will work now

Specify constructor arguments for a Google test Fixture

With Google test I want to specify a Test fixture for use in different test cases.
The fixture shall allocate and deallocate objects of the class TheClass and its data management class TheClassData, where the data management class requires the name of a datafile.
For the different tests, the file name should vary.
I defined the following Fixture:
class TheClassTest : public ::testing::Test {
protected:
TheClassTest(std::string filename) : datafile(filename) {}
virtual ~TheClassTest() {}
virtual void SetUp() {
data = new TheClassData(datafile);
tc = new TheClass(data);
}
virtual void TearDown() {
delete tc;
delete data;
}
std::string datafile;
TheClassData* data;
TheClass* tc;
};
Now, different tests should use the fixture with different file names.
Imagine this as setting up a test environment.
The question: How can I specify the filename from a test, i.e. how to call a non-default constructor of a fixture?
I found things like ::testing::TestWithParam<T> and TEST_P, which doesn't help, as I don't want to run one test with different values, but different tests with one fixture.
As suggested by another user, you cannot achieve what you want
by instantiating a fixture using a non-default constructor. However,
there are other ways. Simply overload the SetUp function and
call that version explicitly in the tests:
class TheClassTest : public ::testing::Test {
protected:
TheClassTest() {}
virtual ~TheClassTest() {}
void SetUp(const std::string &filename) {
data = new TheClassData(filename);
tc = new TheClass(data);
}
virtual void TearDown() {
delete tc;
delete data;
}
TheClassData* data;
TheClass* tc;
};
Now in the test simply use this overload to set up filename:
TEST_F(TheClassTest, MyTestCaseName)
{
SetUp("my_filename_for_this_test_case");
...
}
The parameterless TearDown will automatically clean up when
the test is complete.
Use the current class as a base class for your fixtures:
class TheClassTestBase : public ::testing::Test {
protected:
TheClassTestBase(std::string filename) : datafile(filename) {}
...
};
For every specific filename - use derived fixture:
class TheClassTestForFooTxt : public TheClassTestBase {
protected:
TheClassTestForFooTxt() : TheClassTestBase ("foo.txt") {}
};
However this is extra step needed for every set of parameters - so you can try to use templates or macros to get it done with less effort. Like:
template <typename ClassTestTag>
struct ClassTestParams
{
static std::string filename;
};
template<typename ClassTestTag>
class TheClassTest : public TheClassTestBase {
protected:
TheClassTest() : TheClassTestBase (ClassTestParams<ClassTestTag>::filename) {}
};
Then - for every set of parameters - do that:
class FooTxtTag {};
template <> std::string ClassTestParams<FooTxtTag>::value = "foo.txt";
using TheClassTestForFooTxt = TheClassTest<FooTxtTag>;
TEST_F(TheClassTestForFooTxt, xxxx) {}
However - in your specific case - I would also try GoogleTest:type-parameterized-tests.
Another great way to deal with this is to just extend your fixture and in the extended class supply a new default constructor which calls through to the old one with the arguments you require. For example:
struct MySpecializedTestFixture : public GenericTestFixture
{
MySpecializedTestFixture() : GenericTestFixture("a thing", "another thing") {}
};
TEST_F(MySpecializedTestFixture, FancyTest)
{
// Use the thing environment and make some assertions.
}
If you overload the SetUp method as suggested here, and you want to ensure that you remember to use the overloaded SetUp, you can use an assertion in the TearDown method.
class my_fixture : public ::testing::Test
{
protected:
bool SETUP_HIT_FLAG = false;
void SetUp(double parameter)
{
...
SETUP_HIT_FLAG = true;
}
void TearDown() override
{
assert(SETUP_HIT_FLAG && "You forgot to call SetUp with your parameter!");
}
};
Another way using templates:
template<int N>
class Fixture : public ::testing::Test { ... }
using FixtureForTest = Fixture<1000>;
TEST_F(FixtureForTest, test) { ... }
For this specific case, I feel it is much easier to get rid of the test fixture altogether. The SetUp function can instead be replaced with a helper function that instantiates the class with the required file name. This permits the use of TEST instead of TEST_P or TEST_F. Now each test case is a standalone test which creates its own test class instances with the helper function or directly in the body of the test case.
For example:
using namespace testing;
TEST(FooClassTest, testCase1)
{
FooClass fooInstance("File_name_for_testCase1.txt");
/* The test case body*/
delete fooInstance;
}

Using inheritance in MSTest

I am setting up some MSTest based unit tests. To make my life easier I want to use a base class that handles the generic setup and taredown all of my tests require. My base class looks like this:
[TestClass]
public class DBTestBase {
public TestContext TestContext { get; set; }
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext) {
var config = new XmlConfigurationSource("ARconfig_test.xml");
ActiveRecordStarter.Initialize(Assembly.Load("LocalModels"), config);
}
[TestInitialize()]
public void MyTestInitialize() {
ActiveRecordStarter.CreateSchema();
Before_each_test();
}
protected virtual void Before_each_test() { }
[TestCleanup()]
public void MyTestCleanup() {
After_each_test();
}
protected virtual void After_each_test() { }
}
My actual test class looks like this:
[TestClass]
public class question_tests : DBTestBase {
private void CreateInitialData() {
var question = new Question()
{
Name = "Test Question",
Description = "This is a simple test question"
};
question.Create();
}
protected override void Before_each_test() {
base.Before_each_test();
CreateInitialData();
}
[TestMethod]
public void test_fetching() {
var q = Question.FindAll();
Assert.AreEqual("Test Question", q[0].Name, "Incorrect name.");
}
}
The TestInitialize function works as expected. But the ClassInitialize function never runs. It does run if I add the following to my child class:
[ClassInitialize()]
public static void t(TestContext testContext) {
MyClassInitialize(testContext);
}
Is it possible to get my base class initialize function to run without referencing it in my child class?
ClassInitialize method is executed if and only if the concerned "class" contains at least one TestMethod, and at least one TestMethod from the class is selected for execution.
Confirm this was a problem for me too. I used a constructor on the base and a destructor for the cleanup
[TestClass]
public class question_tests : DBTestBase {
...
[TestCleanup()]
public void TestCleanup()
{
base.MyTestCleanup();
}