Testing file based persistence - unit-testing

we have code that persists a file and I would like to check the content of the file during testing.
I though that such scenario will be best implemented if I abstract the file persistence operation to the following interface:
public interface IFilePersist
{
void Save(XXX, FileLocation);
}
In unit testing I will inject the mock that will check the content and in production the interface will be actually persist to right location.
Is it an overhead? Is this practice commonly used?
For DB related operations this kind of operation is trivial and always used.

Yes, that's one way to do it, if you want to reduce overhead of creating a tracking mock object you may also do a local override of the method if possible. I don't know what language you're using, but in Java a local override would look like this:
// actual class
public class SomeClass {
public void method() {
System.out.println("Hello!");
}
}
// creating the class in test
SomeClass c = new SomeClass() {
public void method() {
System.out.println("Hi!");
}
};
Now your class actually prints "Hi!" when m() is called because it's overriden in an anonymous inner class whilst the actual production class still keeps printing "Hello!".

Yes, it's good to keep unit tests isolated from file system. First because file system access is slower than memory access. Then one can run into other problems (permissions, missing path, FS full or not mounted ...).
The real persistence, on the file system, shall be tested with integration tests.

Related

Gmock const method not called instead calling the original method

I have interface which is defined as
in .h file
namespace diagnostic{
class class1interface{
virtual int readpowerstate()const =0;
virtual int readparameters() = 0;
}
class class1 : public class1interface{
int readpowerstate()const;
int readparameters();}};
in .cc file i have the function
int diagnostic::readparameters(){
if(diagnostic::readpowerstate ==1)
{ //Dothis}
else
{return 0}}
i have to execute the else part since by default the if will get called when i run the program. So i tried to use gmock as follows.
class Mock_class : public diagnostic::class1interface{
public:
Mock_class(){}
MOCK_METHOD0(readparameters,int());
MOCK_CONST_METHOD0(readpowerstate,int());};
and the gmock test i wrote as follows
// Test the failure of Read Parameters
TEST_F(TestBase, readParam_failure){
Mock_class mock_class;
class1 *class_dummmy = new class1();
EXPECT_CALL(mock_class, readpowerstate()).WillOnce(Return(0));
class_dummy->readparameters;
EXPECT_EQ(0, class_dummy->readparameters());}
when i'm executing this program i'm getting the error that
error: Actual function call count doesn't match
EXPECT_CALL(mock_class, readpowerstate())...
Expected: to be called at least once
Actual: never called - unsatisfied and active
what is the solution for this since i'm new to gmock.
Module tests are all about testing an isolated module (like an instance of a selected class) in a mocked environment, specifically, how that module communicates with other objects, and how it responds to various results of these calls. To make this possible, one uses mocks in place of that other real objects. Mock classes allow to both:
configure expectations regarding, e.g., the amount/sequence of calls and/or the values of arguments of these calls to specific functions, and verify those by registering all interactions;
program the results of these expected calls that are returned as if a real object performed some action and responded to the object under test.
This makes it possible to test an object as if it were surrounded by real components, without actually having those. E.g., a device manager can be tested on how it responds to device failures, by mocking a class representing a device and programming that mock to return an error code when some status function is invoked by the manager. That is, no real device class is used, and also, no real (faulty!) device itself is needed to be connected and configured. The mock will pretend to be that device, and what's important, this will all be on a software level.
This, however, is possible only if the class itself is designed in a way that allows us to somehow inject mocked objects in place of their real counterparts. Most importantly, the objects in the system need to communicate via interfaces and virtual calls. That is, the aforementioned device manager should not be communicating with, e.g., DeviceA (a concrete class name), but instead, some DeviceInterface, and so both DeviceA and a newly created mock DeviceMock could implement that interface and be used in that manager. This way the manager will not even know that it is beeing tested and communicates with a mocked object, and not the real device wrapper.
That is, currently, although you create a mock for class1interface you don't actually use that mock. Instead, you try to test class1. Creating a mock for class1interface is useful only if you aim to test some other component (like a class) that communicates with class1 through class1interface, not class1 itself.
So, having a mock for class1, you can e.g. test class2. But this requires this class design to meet the conditions I mentioned previously: communicating via interfaces and ability to inject a mock class.
So to meet the conditions, you'd have to rewrite the code:
int class2::readdata()
{
std::unique_ptr<diagnostic::class1interface> classint
= std::make_unique<diagnostic::class1>();
int value = classint->readparameters();
return value;
}
to (it's just an example of questionable usefulness, you'd have to adjust it to your needs):
int class2::readdata(diagnostic::classinterface* classint)
{
int value = classint->readparameters();
return value;
}
And so you could write a test for class2, injecting a mock of class1:
TEST_F( TestClass2, readParam_failure )
{
// Mocks configuration
Mock_class mock_class;
EXPECT_CALL( mock_class, readparameters() ).WillOnce(Return(0));
// System under test configuration
diagnostic::class2 sut;
// Test itself
EXPECT_EQ( 0, sut.readdata(&mock_class) );
}
This way you check that the call to class2::readdata is properly fowarded to class1interface::readparameters, and its result is returned.

How to test behavior based on private class using members c++ using gtest

I want to use Google test to test my class.
Lets assume I have a state machine implementation and the current state is private
so I have a method SetNextState that looks like that:
void setNextState
{
switch(m_currentState) //m_currentState is a private member
{
case INIT_STATE:
{
if some conditions occurred m_currentState=GO_STATE
}
......
}
}
so I have several cases and each define the behavior to move from certain state to another.
My question:
How do I perform tests on that method assuming the state is relevant only to this class so there is no output
How do I set its value to be, for example "GO_STATE" to test the GO_STATE case
and how do i check the m_currentState at the end of the test
Im trying to avoid putting friends etc. in my UUT code since I want it to be as original as possible
You don't. You do the same thing that your actual program will do, which is provide an input, then examine the result; you say there's no output, but there must be some effect, otherwise the class is pointless!
Failing that, you could make the test a "friend" of the class so that it can inspect its internals, or add an immutable getter for the current state (and who really cares if your class's users get to see that?) but neither option is really in the spirit of the thing.
In my experience, you'll occasionally realise that you're not really unit testing any more but instead functional testing, and Google Test may not be the right tool for that job. If your class is as big as it sounds, that could be the case here. Conversely, you could help yourself by splitting the class into smaller chunks, then unit testing those. Depends what you're going for, really.
Lightness Races in Orbit is correct. However, if sometimes you feel like it's useful to test the private member functions of your class, it often means that your class could be split in multiple smaller pieces.
If you don't think those smaller components are useful to the clients of your library, you can simply hide them in a detail:: namespace and then create unit tests as usual. This will allow you to test the internal behavior of your classes without polluting your public API.
After much considerations I decided to wrap my UUT with a helper which provides set and get to the relevant private members.and use it in the test procedure before calling the tested API
Original code
===============
class UUT //That's the actual class I want to test
{
protected:
int m_protectedMember;
public:
void methodToTest()
{
//Do something with m_protectedMember use its value as input
//and set it as output
}
};
In the tester
==============
class UUTHelper: public UUT
{
public:
int getProtectedMember() { return m_protectedMember; }
void setProtectedMember(int value) { m_protectedMember = value; }
};
The pros:
My test code is very simple and I easily create complicated scenarios .
I test the real code without any "friends" or any other manipulations.
The cons:
As written in the discussion, not the best "good practice", touching private members
Thank you all :)

Should I initialize mock objects in setup or in the test case?

In unit testing with help of mock/fake objects, I wonder whether it's more preferable to initialize the mocks in SetUp or in the test method itself, if my test class contains methods that test the same class (and thus, fake object needed should be the same for all test case). Something like this:
class FooTests
{
Mock<IBar> mockBar;
Foo fooUnderTest;
[SetUp]
public void Setup()
{
mockBar = new Mock<IBar>();
fooUnderTest = new fooUnderTest(mockBar.Object);
}
[Test]
public void MyTest()
{
//setup mock methods
mockBar.SetUp( ... )
//test
fooUnderTest.TestSomething()
//assert something here
}
}
It seems that this will prevent us from duplicating code to mockBar and fooUnderTest in each test case, but the downside is that I have to declare class variables mockBar and fooUnderTest (or is this really a downside?), and it will be problematic if I want to have some special setup (for example, if in some testcase I want to overriede some of the virtual methods of Foo). Any suggestion what is the best practice?
If there is some common setup shared by all tests in a suite/fixture (including setting up some expectations on mock collaborators), MOVE to a Setup method. (Ditto for incidental details that are not relevant to the reader within the test)
If one test case wants to extend common setup, add the specific setup inline within test-case itself
If one test case wants a different setup (inspite of significant overlap), MOVE to different test suite and figure out some other mechanism to share setup (e.g. via composition, utility methods, Object Mothers, etc.)

Unit testing, built in production dependencies

Im reading The Art Of Unit Testing" and there is a specific paragraph im not sure about.
"One of the reasons you may want to avoid using a base class instead of an interface is that a base class from the production code may already have (and probably has) built-in production dependencies that you’ll have to know about and override. This makes implementing derived classes for testing harder than implementing an interface, which lets you know exactly what the underlying implementation is and gives you full control over it."
can someone please give me an example of a built-in production dependency?
Thanks
My interpretation of this is basically anything where you have no control over the underlying implementation, but still rely on it. This could be in your own code or in third party libraries.
Something like:
class MyClass : BaseConfigurationProvider
{
}
abstract class BaseConfigurationProvider
{
string connectionString;
protected BaseConfigurationProvider()
{
connectionString = GetFromConfiguration();
}
}
This has a dependency on where the connection string is returned from, perhaps a config file or perhaps a random text file - either way, difficult external state handling for a unit test on MyClass.
Whereas the same given an interface:
class MyClass : IBaseConfigurationProvider
{
string connectionString;
public MyClass(IBaseConfigurationProvider provider)
{
connectionString = provider.GetConnectionString();
}
}
interface IBaseConfigurationProvider
{
string GetConnectionString();
}
You are in full control of the implementation at least, and the use of an interface means that test versions of implementations can be used during unit tests, or you can inject dependencies into consuming classes (as I have done above). In this scenario, the dependency is on the need to resolve a connection string. The tests can provide a different or empty string.
one example which i can think of is use of Session variable inside that of asp.net (im a .net guy)
because you have no control over how asp.net populates the session variable you cannot test it simply by making a test case you will have to either override it somehow or make a mock object
and this happens because all the context and cookies arent present when you are testing

mock object woes

We have the following problem: a number of classes that we cannot touch but need to unit test them unfortunately the classes are not designed with unit testing in mind so we issues creating mock objects to test the code.
Example:
class SomeOtherClass
{
public:
void foo2() { … }
};
class ClassToTest
{
public:
ClassToTest() {…}
void foo1() { SomeOtherClass A.foo2(); }
};
In the above example we would like to test foo1() but it needs foo2() so we would like to make foo2() belong to a mock object (in real life these functions/classes are vastly more complex and involve interaction with hardware configurations etc thus the need for mock objects/functions). Until now we have done something like this but it is really not optimal because the code seems to have side effects on other unit tests.
class MockSomeOtherClass
{
public:
foo2() { … } // mock function
};
#define SomeOtherClass MockSomeOtherClass
#include “ClassToTest.cpp”
...
Is there a better way to do this without changing the original classes (or with minimal changes)? We use CPPUnit for testing.
EDIT: added tag winapi to more clearly describe out environment.
There is a product called Typemock Isolator++ that appears to address the issues you have raised. I have not tried it yet, so can't comment on how well it works or how easy/difficult it is to use.
Unfortunately, you have to give them your email address to try it. The download is easy enough, but then you are redirected to this page which cheerfully directs you to "Register your software now to get a FREE trial! Please enter your details including a valid email in order to receive your activation key to start using Isolator++."