I am new with c++/tdd, embraced gtest/gmock, and fell in love.
One thing kind of puzzles me though. Are reference pointers really the way to go?
I find myself producing a lot of boiler plate injecting all mocks (even when I don't have any business mocking that behavior).
Example:
namespace
{
class set_configuration_command_tests : public testing::Test
{
protected:
void SetUp() override
{
_uart_peripheral = new uart8_peripheral_mock();
_uart = new uart8_mock(*_uart_peripheral);
_logger = new logger_mock(*_uart);
_mqtt_client = new mqtt_client_mock(*_logger);
_set_configuration_command = new set_configuration_command(*_mqtt_cient);
}
void TearDown() override
{
delete _set_configuration_command;
}
uart8_peripheral_mock *_uart_peripheral;
uart8_mock *_uart;
logger_mock *_logger;
mqtt_client_mock *_mqtt_cient;
set_configuration_command *_set_configuration_command;
};
TEST_F(set_configuration_command_tests, execute_update_configuration)
{
// arrange
// act
// assert
}
}
What I rather did here, is create my sut as
_mqtt_client = new mqtt_client_mock(nullptr); // will not compile of course
_set_configuration_command = new set_configuration_command(*_mqtt_cient);
All the other mocks, I don't need in this case.
Is this the drawback of using reference pointers? Or is there a better approach I should follow?
Found a better alternative. Providing interfaces (pure virtual classes) heavily reduces the need to provide an entire tree of mocks.
e.g
class flash_api : public iflash_api
{
public:
flash_api(iflash_peripheral &flash_peripheral) : _flash_peripheral(flash_peripheral)
{
}
virtual ~flash_api()
{
}
}
Before my mock inherited from flash_api directly. When I gave this class an interface too (`iflash_api') I can let my mock inherit from iflash_api, which gives me a parameter-less constructor.
class flash_api_mock : public iflash_api
{
public:
flash_api_mock()
{
}
virtual ~flash_api_mock()
{
}
}
Then I can write my unit test based on the mocks I actually want to give behavior.
class set_configuration_command_tests : public testing::Test
{
protected:
void SetUp() override
{
_mqtt_cient = new mqtt_client_mock();
_flash_api = new flash_api_mock();
_set_configuration_command = new set_configuration_command(*_mqtt_cient, *_flash_api);
}
void TearDown() override
{
delete _set_configuration_command;
}
flash_api_mock *_flash_api;
mqtt_client_mock *_mqtt_cient;
set_configuration_command *_set_configuration_command;
};
Related
I have implemented a Dependency Injection pattern in my code. I did that to be able to mock a service using gmock. The DI implementation works in production code, however, I am having trouble with my test setup. When using the EXPECT_CALL macro, I get "expression must have class type" error. I believe this is related to the way I designed the dependency, but I can't find an alternative solution (lack of experience). I have browsed previous threads on similar issues, but none helped. Would you be kind to take a look at the code below and hint possible workarounds (simplified code example using a Car-Engine interface)?
// Engine interface class with pure virtual functions
class IEngine
{
public:
virtual ~IEngine() = default;
virtual void start() = 0;
virtual void stop() = 0;
};
// A V8Engine class implementing this interface
class V8Engine : public IEngine
{
public:
void start() override { std::cout << "V8 Engine started\n"; };
void stop() override { std::cout << "V8 Engine stopped\n"; };
};
// Car.h file
class Car
{
public:
Car(IEngine *engineService);
void Drive();
private:
IEngine* mEngine = nullptr;
};
// Car.cpp file
Car::Car(IEngine* engineService)
: mEngine(engineService)
{
if (mEngine == nullptr)
{
throw std::invalid_argument("service must not be null");
}
}
void Car::Drive()
{
mEngine->start();
mEngine->stop();
}
I would like to be able to mock the engine implementation and instead of using a "real V8Engine", utilize the mock. Here is how I set up my test:
class MockEngine : public IEngine
{
public:
MOCK_METHOD(void, start, (), (override));
MOCK_METHOD(void, stop, (), (override));
};
TEST(TestCarClass, TestCarWithMockEngine)
{
IEngine *mockEngine = new MockEngine;
Car carUnderTest(mockEngine);
carUnderTest.Drive();
EXPECT_CALL(mockEngine, start()); // This is the part where I get the error due to invalid mockEngine setup
}
EXPECT_CALL expects mock object as first parameter, you pass reference to mock.
either use *mockEngine:
TEST(TestCarClass, TestCarWithMockEngine)
{
IEngine *mockEngine = new MockEngine;
Car carUnderTest(mockEngine);
EXPECT_CALL(*mockEngine, start());
carUnderTest.Drive();
}
or avoid allocation directly:
TEST(TestCarClass, TestCarWithMockEngine)
{
MockEngine mockEngine;
Car carUnderTest(&mockEngine);
EXPECT_CALL(mockEngine, start());
carUnderTest.Drive();
}
Let's say I have a dagger 2 module as follows,
#Module
interface Creator {
MyClass create();
}
and I am using it to create an instance of MyClass
class Instantiator {
void doSomething(){
MyClass clazz = DaggerCreator.create().create();
// do things with clazz
}
}
It seems to me that I cannot effectively test the doSomething method in Instantiator because I cannot provide a mock for MyClass.
Am I wrong? If not are we supposed to use Dagger instantiation sparingly?
You are correct in saying that it is hard to test use of a Component injector, since this is a static method. But harder than what? Here is the same method using instantiation:
class Instantiator {
void doSomething(){
MyClass clazz = new MyClass();
// do things with clazz
}
}
still hard to test, right?
The point is to use as few Component (injectors) as possible and to pass in dependencies in the constructor for your objects. Dagger 2 makes resolving the dependencies in the constructor easy. This thereby makes testing easy since you can pass in mock object in a constructor.
Let's refactor the code you wrote to be testable. Assume that MyClass contains a single method, fireLazers() that you want to test is being invoked inside Instantiator's doSomething() method:
public class DoerOfSomething {
private final MyClass myClass;
#Inject
public DoerOfSomething(MyClass myClazz) {
this.myClass = myClazz;
}
public void doSomething() {
myClass.fireLazers();
}
}
Now you can write a test like this using a mock object:
public void DoerOfSomethingTest {
//mocks
MyClass mockMyClass;
//system under test
DoerOfSomething doerOfSomething;
#Before
public void setUp() {
mockMyClass = Mockito.mock(MyClass.class);
}
#Test
public void whenDoSomething_thenInteractsWithMyClass() {
//arrange
doerOfSomething = new DoerOfSomething(mockMyClass);
//act
doerOfSomething.doSomething();
//assert
verify(mockMyClass).fireLazers();
}
}
Of course, you will now need to inject DoerOfSomething into the top level class where you are injecting, but now you can be certain that the object you are injecting is functioning as expected because it is testable. Your code for using Dagger looks a bit unusual but I'll use your idioms for the sake of parity between the question and the answer.
class Instantiator {
private final DoerOfSomething doerOfSomething;
Instantiator() {
doerOfSomething = DaggerCreator.create().create();
}
void doSomething() {
doerOfSomething.doSomething();
}
}
I am unit testing legacy code and I am dealing with a class that instantiates another class. I believe this is testable using Microsoft Fakes, but am wondering if NSubstitute has the capability. I believe the answer is no, but need to be sure.
public class ClassA
{
public int MethodA()
{
int reportId = this.MethodB();
return reportId;
}
public virtual int MethodB()
{
ClassC c = new ClassC();
return c.MethodA();
}
}
public class ClassC
{
public virtual int MethodA()
{
return 2;
}
}
[Test]
public void Test_ClassA()
{
ClassA subclassA = new ClassA();
var subclassC = Substitute.For<ClassC>(); //this is pointless the way I have it here
subclassC.MethodA().Returns(1); //this is pointless the way I have it here
int outValue = subclassA.MethodA();
Assert.AreEqual(outValue, 1); //outvalue is 2 but I would like it to be 1 if possible using Nsubstitute
}
It is possible to override virtual methods in classes by using partial substitution: just make sure that the base code cannot be called by specifying that the base class must not be called:
var A = Substitute.ForPartsOf<ClassA>();
var C = Substitute.ForPartsOf<ClassC>();
C.When(c => c.MethodA()).DoNotCallBase();
C.MethodA().Returns(10);
A.When(a => a.MethodB()).DoNotCallBase();
var cResult = C.MethodA();
A.MethodB().Returns(cResult);
Console.WriteLine(A.MethodB());
Console.WriteLine(C.MethodA());
Hi say I have some code like:
public class Class1
{
public int MyMethod()
{
return MyOtherMethod();
}
public virtual int MyOtherMethod()
{
return 1;
}
}
Ok, this doesn't do much of relevance but this is just for a simple example.
I then create a new test:
[TestMethod]
public void TestMethod1()
{
var t = new Mock<Class1>();
var w = t.Object.MyMethod();
}
Could someone please tell me why the code runs through the called method MyOtherMethod when it's not designated as virtual but when you make it virtual the test code refuses to go through that method?
You should setup the virtual method before you calling MyMethod:
t.Setup(c => c.MyOtherMethod()).Return(1);
I have code that uses MoQ to create a partial stub. I'd prefer to interact with the interface instead of the concrete implementation so that I won't have to modify the unit test if I have a different implementation of the interface.
So for example, I have a factory method such as:
private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
return new Mock<SomeConcreteImplementation>();
}
Here is the code that calls the method:
var partialStub = ISomeInterfaceStubFactory();
partialStub.Setup(m => m.MethodToStubOutThatMethodToTestCalls(It.IsAny<string>())).Returns(new List<SomeOtherObject>());
partialStub.CallBase = true;
var actualResult= partialStub.Object.MethodToTest();
Assert.That(actualResult, Is.EqualTo(expectedResult));
The problem is that when doing this is that ISomeInterfaceStubFactory won't compile. So I changed it to be like below, but doing this seems to break the partial stub. The actual implemented MethodToStubOutThatMethodToTestCalls operation gets called, not the stubbed version. Basically I'm trying to use polymorphism with the stub object. Is there anyway to do this? I'd like my unit test to not be highly coupled to the concrete implementation.
private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
return new Mock<SomeConcreteImplementation>.As<ISomeInterface>();
}
I think you are missing the point of mock objects. Returning a mock from a concrete implementation makes no sense. The idea is to have the class under test depend on some interface or abstract which you could mock.
Revising my answer per your clarification. I don't disagree with arootbeer, but I do want to understand what you are doing and why it doesn't work.
Here's a simple example of what I think you are trying to do. The test passes for me for both concrete implementations. Is this what you are trying to do, and does this example work for you?
Interface and classes:
using System;
namespace ClassLibrary1
{
public interface IFoo
{
string GetBaseString();
string GetExtendedString();
}
public class Foo_A : IFoo
{
public virtual string GetBaseString()
{
return "Foo_A";
}
public virtual string GetExtendedString()
{
return GetBaseString() + "_Bar";
}
}
public class Foo_B : IFoo
{
public virtual string GetBaseString()
{
return "Foo_B";
}
public virtual string GetExtendedString()
{
return GetBaseString() + "_Bar";
}
}
}
Unit test:
using System;
using Xunit;
using Moq;
namespace ClassLibrary1.UnitTests
{
public class Class1
{
[Fact]
public void GetExtendedString_ReturnsExtendedString()
{
var partialFoo = IFooFactory();
partialFoo.Setup(x => x.GetBaseString()).Returns("Foo");
partialFoo.CallBase = true;
string result = partialFoo.Object.GetExtendedString();
Assert.Equal("Foo_Bar", result);
}
private Mock<IFoo> IFooFactory()
{
return new Mock<Foo_A>().As<IFoo>();
//return new Mock<Foo_B>().As<IFoo>();
}
}
}