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.
Related
Google recommends to use the text fixture constructor/destructor when possible instead of SetUp()/TearDown() (https://google.github.io/googletest/faq.html#CtorVsSetUp). Assuming I do it this way, what is the use of even using a test fixture? How are the following different, and what is the advantage of the first?
TEST_F(MyFixture, MyTest) {
... run test, using member functions of MyFixture for common code ...
}
TEST(MySuite, MyTest) {
MyFixture fixture; // will call ctor
... run test, using public functions of MyFixture for common code ...
} // will call dtor
The advantages are visible when there are more than one TEST/TEST_F.
Compare:
TEST(MyTest, shallX)
{
MyTest test;
test.setUpX();
test.objectUnderTest.doX();
}
TEST(MyTest, shallY)
{
OtherTest test;
test.setUpY();
test.objectUnderTest.doY();
}
with
TEST_F(MyTest, shallX)
{
setUpX();
objectUnderTest.doX();
}
TEST_F(MyTest, shallY)
{
setUpY();
objectUnderTest.doY();
}
What we can see, are:
DRY (don't repeat yourselves) principle is followed. You do not have to repeat creating of some test-helper object. In TEST_F - the macro creates this instance.
The code is safer with TEST_F. See MyTest..shallDoY -- have you spot that wrong test-helper object is used, not the one that testname is promising.
So it is better to use TEST_F if your tests require some test-helper class.
If not - then use TEST.
I'm attempting to write Mocks for Private / Non Virtual / Static functions and come across a way to do the same.
Here is how it looks like..
Lets assume that I have a class A which needs to be mocked and used inside class UsingA. The definition of both classes looks like
class A
{
friend class UsingA;
int privateFn() {}
public:
int nonVirtual() {}
};
// The UsingA class
class UsingA {
A &a1;
public:
UsingA(A & _a1) : a1(_a1) {}
int CallFn() {
return a1.nonVirtual();
}
int CallFn2() {
return a1.privateFn();
}
};
I know that Mocks are meant for generating the behavior of the class and while creating Mocks, we need to derive from the original class.
However, to Mock the behavior I decided not to derive from the original class, instead comment the class A and generate a Mock class with the same Name i.e class A.
Here is how my mock class looks like
// Original class A is commented / header file removed
class A {
public:
MOCK_METHOD0(nonVirtual, int());
MOCK_METHOD0(privateFn, int());
};
And my tests are usual mock tests
TEST(MyMockTest, NonVirtualTest) {
A mstat;
UsingA ua(mstat);
EXPECT_CALL(mstat, nonVirtual())
.Times(1)
.WillOnce(Return(100));
int retVal = ua.CallFn();
EXPECT_EQ(retVal,100);
}
TEST(MyMockTest, PrivateTest) {
A mstat;
UsingA ua(mstat);
EXPECT_CALL(mstat, privateFn())
.Times(1)
.WillOnce(Return(100));
int retVal = ua.CallFn2();
EXPECT_EQ(retVal,100);
}
And everything works fine and I'm able to test UsingA by this mock.
Question is.
This looks easier and serves the purpose, still I haven't seen this kind of examples while browsing for google mock examples. Is there anything that would go wrong if I do this?
Honestly, I didn't find any.
NOTE: Folks, I'm using friend for demonstration only. My actual use case is totally different. Thanks
The wrong is that you are not testing real code, because of that:
comment the class A
generate a Mock class with the same name
These operations alter the code under test.
An example what can go wrong:
Change return type: long nonVirtual in Mock - previously was int
Test that on, let say, nonVirtual() == 0xFF'FFFF'FFFF (which is bigger than INTMAX) some action is being done
Forget to change in real A - so real UsingA have branch that is tested but never reachable in real code
An example code:
class A {
public:
MOCK_METHOD0(nonVirtual, long()); // change
MOCK_METHOD0(privateFn, int());
};
void UsingA::processA()
{
if (a.nonVirtual() > VERY_BIG_NUMBER)
{
throw runtime_error("oops");
}
}
TEST_F(UsingATest, throwOnVeryBigNumber)
{
EXPECT_CALL(aMock, nonVirtual()).WillOnce(Return(VERY_BIG_NUMBER + 1));
ASSERT_THROW(objectUndertTest.processA());
}
But real A did not change - so we test non reachable code in UsingA class:
class A {
public:
int nonVirtual(); // not changed
...
};
The best solution is (in order):
To test in isolation you have to isolate classes - so to use dependency injection (virtual functions etc, base interfaces, etc...) - this is sometimes called London School of TDD
Test both classes A and UsingA w/o any stubbing - test them together in one testcase - thus you test real code - this is called Detroit Shool of TDD
Separate by template code with good restriction on interface - this approach is most similar to yours:
Regarding 3 - you might use something like this:
template <class T = A>
class UsingA {
T &a1;
public:
UsingA(T & _a1) : a1(_a1) {}
long CallFn() {
using ANonVirtualResult = std::invoke_result_t<&T::nonVirtual>;
static_assert(std::is_same<long, ANonVirtualResult>::value);
return a1.nonVirtual();
}
...
};
And in test:
class UsingATest : public ::testing::Test
{
protected:
StrictMock<AMock> aMock;
using ClassUnderTest = UsingA<AMock>;
ClassUnderTest objectUnderTest{aMock};
};
TEST_F(UsingATest, useNonVirtual)
{
const auto VALUE = 123456;
EXPECT_CALL(aMock, nonVirtual()).WillOnce(Return(VALUE));
ASSERT_EQ(VALUE, objectUnderTest.CallFn());
}
You might note that some assumption about A might be tested during compilation as static_assert or via some SFINAE technics (more complicated).
Actually, there are examples with template code in googlemock as workaround for mocking classes w/o virtual functions.
We use your type of using mocks inside a few of our test projects to check callbacks on a larger class that we pass along using dependency injection. In our case, the methods are declared virtual.
In your case, they are not. Your mock implementation would hide the original implementation - if there was any. So I don't think there's an issue here.
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.
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
I've done writing code on salesforce and in order to release the unit tests have to cover at least 75%.
What I am facing is that the classOne that calls methods from classTwo also have to cover classTwo's unit test within classOne even though it is done in classTwo file already.
File MyClassTwo
public with sharing class ClassTwo {
public String method1() {
return 'one';
}
public String method2() {
return 'two';
}
public static testMethod void testMethod1() {
ClassTwo two = new ClassTwo();
String out = two.method1();
system.assertEquals(out, 'one'); //valid
}
public static testMethod void testMethod2() {
ClassTwo two = new ClassTwo();
String out = two.method2();
system.assertEquals(out, 'two'); // valid
}
}
File MyClassOne
public with sharing class ClassOne {
public String callClassTwo() {
ClassTwo foo = new ClassTwo();
String something = foo.method1();
return something;
}
public static testMethod void testCallClassTwo() {
ClassOne one = new ClassOne();
String out = one.callClassTwo();
system.assertEquals(out, 'one');
}
}
The result of testing MyClassOne would not return 100% test coverage because it says I have not covered MyClassTwo method2() part inside of MyClassOne file.
But I already wrote unit test for MyClassTwo inside of MyClassTwo file as you can see.
So does this mean I have to copy and paste the unit test in MyClassTwo file over to MyClassOne?
Doing so gives me 100% coverage but this seems really annoying and rediculous. Having same test in ClassA and ClassB....? Am I doing wrong or is this the way?
Having said, is it possible to create mock object in salesforce? I haven't figure how yet..
http://sites.force.com/answers/ideaView?c=09a30000000D9xt&id=087300000007m3fAAA&returnUrl=/apex/ideaList%3Fc%3D09a30000000D9xt%26category%3DApex%2B%2526%2BVisualforce%26p%3D19%26sort%3Dpopular
UDPATE
I re-wrote the code and updated above, this time for sure classOne test would not return 100% even though it is not calling classTwo method2()
Comments about Java mock libraries aren't very helpful in Salesforce world ;) At my projects we usually aimed for making our own test data in the test method, calling real functionality, checking the results... and whole test framework on Salesforce side is responsible for transaction rollback (so no test data is saved to DB in the end regardless whether the test failed or passed).
Anyway...
Masato, your classes do not compile (methods outside class scope, public String hello() without any String returned)... After I fixed it I simply right-clicked the MyClassA -> Force.com -> run tests and got full code coverage without any problems so your issue must lie somewhere else...
Here's how it looks: http://dl.dropbox.com/u/709568/stackoverflow/masato_code_coverage.png
I'm trying to think what might have gone wrong... are you sure all classes compile and were saved on server side? Did you put test methods in same classes as functionality or in separate ones (generally I make separate class name with similar name like MyClassATest). If it's a separate class - on which file did you click "run tests"?
Last but not least - if you're facing this issue during deployment from sandbox to production, make sure you selected all classes you need in the deployment wizard?
If you really want to "unit" test, you should test the behavior of your class B AND the behavior of your class A, mocking the call to the class B method.
That's a tough conversation between mock lovers and others (Martin Fowler I think is not a "mocker").
Anyway. You should stop thinking about 100% coverage. You should think about:
Why am i testing?
How am i testing?
Here, i'd definitely go for 2 tests:
One test for the B class into the b class test file to be sure the B method is well implemented, with all the side effects, side values etc.
one test for the A class mocking the class B
What is a mock?
To stay VERY simple: A mock is a portion of code in your test which is gonna say: when the B class method is called, always return this value: "+++" .
By doing this, you allow yourself having a maintanable and modulable test suite.
In java, I love mockito : http://mockito.org/
Although one of my colleagues is lead maintainer for easymock: http://easymock.org/
Hope this helps. Ask me if you need further help.
EDIT SOME EXAMPLE
With Java and mockito:
public class aUTest {
protected A a;
#Mock protected B b;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
a = new A();
ReflectionTestUtils.setField(a, "b", b);
}
#Test
public void test_A_method_should_not_throw_exception()
when(b. execute()).thenReturn(true); //just an example of a return value from b. execute()
Boolean result = a.testHello();
// Assert
Assert.assertEquals(true, result);
}
I created an Apex class called TestHelper for all my mock objects. I use constants (static final) for values that I might need elsewhere and public static fields for objects. Works great and since no methods are used, no test coverage is needed.
public without sharing class TestHelper {
public static final string testPRODUCTNAME = 'test Product Name';
public static final string testCOMPANYID = '2508';
public static Account testAccount {
get{
Account tAccount = new Account(
Name = 'Test Account',
BillingStreet = '123 Main St',
BillingCity = 'Dallas',
BillingState = 'TX',
BillingPostalCode = '75234',
Website = 'http://www.google.com',
Phone = '222 345 4567',
Subscription_Start_Date__c = system.today(),
Subscription_End_Date__c = system.today().addDays(30),
Number_Of_Seats__c = 1,
companyId__c = testCOMPANYID,
ZProduct_Name__c = testPRODUCTNAME);
insert tAccount;
return tAccount;
}
}
}