I want to test makeTvSeries() method without extracting getNumberOfShows, printMsg to other class and then mocking it so I thougth about mocking TvChannel class.
Is it possible to call base class method (makeTvSeries) which will call child methods: getNumberOfShows, printMsg without getting rid of virtuality? So I could use same mock class definiton in other tests for instance foo.playTvSeries(mockTvChannel) and expect calls to makeTvSeries?.
Moreover is it good practice what I am doing at all? In whole program there are also other classes which use cin and cout and as I said at the begining I didn't wanted to extract all of them to one class responsible for input/output. What are Yours experiences and what I should do ?
class MockTvChannel : public TvChannel{
public:
MOCK_METHOD0(getNumberOfShows, int());
//MOCK_METHOD0(makeTvSeries, void());
MOCK_METHOD0(printMsg, void());
};
TEST(sample_test_case, sample_test)
{
MockTvChannel channel;
EXPECT_CALL(channel, getNumberOfShows())
.Times(1)
.WillOnce(::testing::Return(10));
EXPECT_CALL(channel, printMsg())
.Times(10);
channel.makeTvSeries();
}
class TvChannel
{
protected:
virtual int getNumberOfShows(){
int nShows;
std::cin >> nShows;
return nShows;
}
virtual void printMsg(){
std::cout << "What a show!" << std::endl;
}
public:
/*virtual*/ void makeTvSeries()
{
int nShows = getNumberOfShows();
for(int i = 0; i<nShows; ++i){
printMsg();
}
}
virtual ~TvChannel() {};
};
So I could use same mock class definiton in other tests for instance foo.playTvSeries(mockTvChannel) and expect calls to makeTvSeries?
Yes, you can. And your implementation is fine.
is it good practice what I am doing at all?
It is. Following the SOLID principle, you applied next principles :
LSP : in unit test you switched real implementation and tested using mock, so your makeTvSerier works
ISP : your class has an interface
DIP : I guess, you want to use inversion of control when you pass instance of mock to other objects
Related
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.
Let’s say I’m writing a car class. It should have the methods configEngine and currentGasolineConsumption beside some other methods. So I refactored out the calculation of the gasoline consumption into an Engine class and use polymorphism to get the current gasoline consumption:
class AbstractEngine()
{
public:
virtual int calculateGasolineConsumption()
{
//... do calculation ...
return consumption;
}
// some other (pure virtual) methodes
};
class EngineA() : public AbstractEngine
{
public:
// implementation of the pure virtual methodes
};
class EngineB() : public AbstractEngine
{
public:
// implementation of the pure virtual methodes
};
class EngineC() : public AbstractEngine
{
public:
// implementation of the pure virtual methodes
int calculateGasolineConsumption() override
{
//... do new calculation ...
return consumption;
}
};
enum EngineType {
ENGINE_A,
ENGINE_B,
ENGINE_C,
};
void configEngine(EngineType engineType)
{
m_engine = m_engineFactory.create(engineType);
}
int currentGasolineConsumption()
{
return m_engine.calculateGasolineConsumption();
}
Now my question is how to unittest this without getting duplication in my unit tests?
If I write three unittests, for configEngine(ENGINE_A) and configEngine(ENGINE_B) would test basically the same code of the abstract superclass and I don’t like that duplication.
struct EngineSpec {
EngineType engineType;
int expectedValue;
};
INSTANTIATE_TEST_CASE_P(, tst_car, ::testing::Values(
EngineSpec { ENGINE_A, 3 },
EngineSpec { ENGINE_B, 3 },
EngineSpec { ENGINE_C, 7 }
));
TEST_F(tst_car,
currentGasolineConsumption_configWithEngine_expectedBehaviour)
{
EngineSpec engineSpec = GetParam();
//Arrange
m_car.configEngine(engineSpec.engineType);
//Act
auto result = m_car.currentGasolineConsumption();
//Assert
EXPECT_EQ(engineSpec.expectedValue, result);
}
Of course there is only one duplicate/unnecessary unittest but this is only a minimal example. In my real code the number of unit test duplication would explode.
One additional thing: I don’t want to move the Engine class outside of the ‘module’ and use dependency injection because I think this ‘internal Engine class’ approach is easier to handle for the client. So the client has only one interface and some enums to use this module. I would like to treat the Engine class as implementation detail.
Ideally tests should know as little about the implementation as possible, because 10 years down the line when the abstraction doesn't quite work any more, or is part of a large complicated inheritance chain (e.g. what happens when you get a hybrid engine?) the tests that appear to be a lot of effort right now will still work perfectly.
However, if you want to be pragmatic and don't mind coupling your tests to the implementation a little, you could extract a testGasolineConsumption(AbstractEngine engine) method that is called from a test case for each child. This would check that the implementation works correctly and that the base class behaviour hasn't been overridden.
Which approach is better: I tried to find it on web, but I couldn't get a better answer.
1.
public class OtherClass
{
public int Add(int x, int y)
{
return x + y;
}
}
public class TestClass
{
OtherClass oClass = new OtherClass();
public int Fun1()
{
return oClass.Add(1,2);
}
public int Fun2()
{
return oClass.Add(1, 2);
}
}
2.
public class TestClass
{
public int Fun1()
{
OtherClass oClass = new OtherClass();
return oClass.Add(1, 2);
}
public int Fun2()
{
OtherClass oClass = new OtherClass();
return oClass.Add(1, 2);
}
}
I think it depends on what you are trying to test.
If you're testing the effects of a sequence of functions being executed on the same class instance then you might want to create a single instance (such as stress testing)
But otherwise I'd say it's always better to create a new instance of the class in each test function to ensure that the context of each test is predictable. If your test methods shared an instance of a class, and one test method fails and corrupts the state of the object under test, your subsequent test may fail for no other reason than the state of the object under test was corrupted by the previous failed test (it might appear the multiple tests are failing when in fact only one of the early ones is a true failure).
Depends on the scenario, if the class is gonna be shared on multiple functions and there are no specific arguments needed to create an instance of that class then it's better of being at the class level.
Let's say you're using the Fun1 and Fun2 often, having the instance creation on the method will have instance creation overhead rather than it being at the class level having a single instance, or better yet, make it static or make it singleton if you're sure that it's going to be a single instance throughout the whole app.
One benefit of having it in the class level is if you're doing unit testing, you can make an interface like IOtherClass and Inject it in the constructor of TestClass.
It would look something like this.
public class OtherClass : IOtherClass
{
public int Add(int x, int y)
{
return x + y;
}
}
public class TestClass
{
IOtherClass oClass;
public TestClass(IOtherClass _oClass)
{
oClass = _oClass;
}
public int Fun1()
{
return oClass.Add(1,2);
}
public int Fun2()
{
return oClass.Add(1, 2);
}
}
You're better off having it as a field in the class rather than declaring a new one in each method. The reason for this is simple, there won't be a line of code in each method declaring the variable meaning that if your declaration statement changes you will only have to change it in one place, not every method. Also it will make your code easier to read and add to because this line won't be duplicated everywhere.
Just remember if that field needs to be disposed your class should implement the IDisposable interface.
Can anyone help me with this? basically I have a test class, wihtin this test class I have a number of methods which all use the same type of setup. Let me show you by example:
class Test:public CxxTest::TestSuite
{
public:
void Test1(){/*...*/}
void Test2(){/*...*/}
};
Each test method requires the same type of setup:
Class c_objectName = AnotherClass::method("c_name","c_name","c_name");
class c_newObjectName = AnotherCLass::create(c_objectName);
I am currently setting this in every single method, because each of the above i started with "c_..." needs to be different.
I tried to make a "global method" that would take in a string to rename these each time, but then I cant seems to access them from the method calls. I tried the following:
class Test:public CxxTest::TestSuite
{
public:
void method()
{ Class c_objectName = AnotherClass::method("c_name","c_name","c_name"); <--- cant access these
Class c_newObjectName = AnotherClass::create(c_objectName);
}
void Test1(){/*...*/}
void Test2(){/*...*/}
};
Is there a way to put this in a "global method" of some sort so that I can access these from the methods?
Im really bad at explaining things so sorry and thanks in advance
I can't make heads and tails of the question, but it looks like something like this would help:
struct TestFixture
{
Class c_objectName;
Class c_newObjectName;
};
TestFixture makeFixture()
{
TestFixture fixture;
fixture.c_objectName = new Class("c_name","c_name","c_name");
fixture.c_newObjectName = create(c_objectName);
return fixture;
}
(assuming your Class (classes?) are copyable. If not, return a pointer to a new instance of TestFixture or something like scoped_ptr
Then you could use it in your test methods:
void Test1()
{
TestFixture fixture = makeFixture();
// use fixture.c_objectName etc.
If you don't mind sharing the data, you could just make them fields of class Test.
Edit Oh, I just realized you are using CxxTest, which probably has a better way of creating fixtures/setup/teardown for unit tests. However, the above approach should work in any framework.
I'm trying to start using Unit Testing on my current project in Visual Studio 2010. My class structure, however, contains a number of interface and abstract class inheritance relationships.
If two classes are derived from the same abstract class, or interface I'd like to be able to share the testing code between them. I'm not sure how to do this exactly. I'm thinking I create a test class for each interface I want to test, but I'm not sure the correct way to feed my concrete classes into the applicable unit tests.
Update
OK here's an example. Say I have an interface IEmployee , which is implemented by an abstract class Employee, which is then inherited by the two concrete classes Worker and Employee. (Code show below)
Now say I want to create tests that apply to all IEmployees or Employees. Or alternatively create specific tests for specific types of Employees. For example I may want to assert that setting IEmployee.Number to a number less then zero for any implementation of IEmployee throws an exception. I'd prefer to write the tests from the perspective of any IEmployee and then be able to use the tests on any implementation of IEmployee.
Here's another example. I may also want to assert that setting the vacation time for any employee to a value less then zero throws and error. Yet I may also want to have different tests that apply to a specific concrete version of Employee. Say I want to test that Worker throws an exception if they are provided more then 14 days vacation, but a manager can be provided up to 36.
public interface IEmployee
{
string Name {get; set;}
int Number {get; set;}
}
public abstract class Employee:IEmploee
{
string Name {get; set;}
int Number {get;set;}
public abstract int VacationTime(get; set;)
}
public abstract class Worker:IEmployee
{
private int v;
private int vTime;
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>36) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}
public void DoSomWork()
{
//Work
}
}
public abstract class Manager:IEmployee
{
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>14) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}
public void DoSomeManaging()
{
//manage
}
}
So I guess what I'm looking for is a work flow that will allow me to nest unit tests. So for example when I test the Manager class I want to first test that it passes the Employee and IEmployee tests, and then test specific members such as DoSomeManaging().
I guess I know what you mean. I had the same issue.
My solution was to create a hierarchy also for testing. I'll use the same example you show.
First, have an abstract test class for the base IEmployee.
It has two main things:
i. All the test methods you want.
ii. An abstract method that returns the desired instance of the IEmployee.
[TestClass()]
public abstract class IEmployeeTests
{
protected abstract GetIEmployeeInstance();
[TestMethod()]
public void TestMethod1()
{
IEmployee target = GetIEmployeeInstance();
// do your IEmployee test here
}
}
Second, you have a test class for each implementation of IEmployee, implementing the abstract method and providing appropriate instances of IEmployee.
[TestClass()]
public class WorkerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Worker();
}
}
[TestClass()]
public class ManagerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Manager();
}
}
You can see everything works as expected and VS gives you the expected test methods for each WorkerTests and ManagerTests classes in the TestView window.
You can run them and have the test results for each implementation of the IEmployee interface, having to create the tests only in the base IEmployeeTests class.
You can always add specific test for the derived WorkerTests and ManagerTests classes.
The question would be now, what about classes that implement multiple interfaces, let's say EmployedProgrammer?
public EmployedProgrammer : IEmployee, IProgrammer
{
}
We don't have multiple inheritance in C#, so this is not an option:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests, IProgrammerTests
{
// this doesn't compile as IEmployeeTests, IProgrammerTests are classes, not interfaces
}
For this scenario, a solution is to have the following test classes:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new EmployedProgrammer();
}
}
[TestClass()]
public EmployedProgrammerIProgrammerTests : IProgrammerTests
{
protected override GetIProgrammerInstance()
{
return new EmployedProgrammer();
}
}
with
[TestClass()]
public abstract class IProgrammerTests
{
protected abstract GetIProgrammerInstance();
[TestMethod()]
public void TestMethod1()
{
IProgrammer target = GetIProgrammerInstance();
// do your IProgrammerTest test here
}
}
I'm using this with good results.
Hope it helps.
Regards,
Jose
What I think you want to do is create unit tests for methods in abstract classes.
I'm not sure it makes sense to want to test a protected method on an abstract class, but if you insist simply extend the class in a class used exclusively for unittesting. That way you can expose the protected methods on the abstract class you want to test through public methods on the extending class that simply call through to the method on the abstract class.
If you have methods in abstract classes that you want unittested, I suggest refactoring them into separate classes and simply expose them as public methods and put those under test. Try looking at your inheritance tree from a 'test-first' perspective and I'm pretty sure you'll come up with that solution (or a similar one) as well.
It seems that you have described "composite unit testing" which is not supported by Visual Studio 2010 unit tests. Such things can be done in MbUnit according to this article. It is possible to create abstract tests in Visual Studio 2010 which is probably not exactly what you want. Here is description how to implement abstract tests in VS (Inheritance Example section).
Use microsoft moles for better testing. so you can mock the abstract base class / static methods etc easily. Please refer the following post for more info
detouring-abstract-base-classes-using-moles
BenzCar benzCar = new BenzCar();
new MCar(benzCar)
{
Drive= () => "Testing"
}.InstanceBehavior = MoleBehaviors.Fallthrough;
var hello = child.Drive();
Assert.AreEqual("Benz Car driving. Testing", hello);
The desire to run the same test against multiple classes usually means you have an opportunity to extract the behavior you want to test into a single class (whether it's the base class or an entirely new class you compose into your existing classes).
Consider your example: instead of implementing vacation limits in Worker and Manager, add a new member variable to Employee, 'MaximumVacationDays', implement the limit in the employee class' setter, and check the limit there:
abstract class Employee {
private int maximumVacationDays;
protected Employee(int maximumVacationDays) {
this.maximumVacationDays = maximumVacationDays
}
public int VacationDays {
set {
if (value > maximumVacationDays)
throw new ArgumentException("Exceeded maximum vacation");
}
}
}
class Worker: Employee {
public Worker(): Employee(14) {}
}
class Manager: Employee {
public Manager(): Employee(36) {}
}
Now you have only one method to test and less code to maintain.