I am trying to do a unit test to test the DoLogin method:
CLoginActivity::CLoginActivity()
{
m_pTask = new Task();
}
void CLoginActivity::DoLogin()
{
m_pTask.execute();
}
where the Task is another class that I need to mock.
class MockTask : public Task
{
public:
MOCK_METHOD0(Execute, void());
};
To inject the MockTask task object, I must change my construction:
CLoginActivity::CLoginActivity(Task& task)
{
m_pTask = task;
}
or write a set function:
CLoginActivity::SetTask(Task& task)
{
m_pTask = task;
}
Is there other method to inject instead those two methods? And I use gmock in my unit test project.
Injecting via constructor is the best - keep this design.
But there are few others ways for people that like to complicate simple things.
1) Make your CLoginActivity class template:
template <class TaskImpl>
class CLoginActivityTemplate
{
CLoginActivityTemplate() { m_pTask = new TaskImpl(); }
};
using CLoginActivity = CLoginActivityTemplate<Task>;
In your tests, test this instantion:
using CLoginActivityTestable = CLoginActivityTemplate<TaskMock>;
However it is not always so easy - because it is often hard to get access to this mock to set expentantions on it. But you might define TestMockWrapper class
to ensure access to mock task is easy:
class TestMockWrapper : public TestMock
{
public:
static TestMock* lastCreated;
TestMockWrapper() { lastCreated = this; }
};
using CLoginActivityTestable = CLoginActivityTemplate<TaskMockWrapper>;
2) Inject factory object to your constructor:
CLoginActivity::CLoginActivity(ITaskFactory& taskFactory)
{
m_pTask = taskFactory.create();
}
You need to mock this factory class to ensure mock-factory creates mock-object. Maybe it does not look promissing - but this is just intro to next point.
3) Have special factory function implemented in other file:
CLoginActivity.cpp
#include "TaskCreate.hpp"
CLoginActivity::CLoginActivity()
{
m_pTask = taskCreate();
}
TaskCreate.cpp
// your "real" function here
ITask* createTask() { return new Task(); }
Having such design- create UT test for your CLoginActivity with using only selected files from your projects - simple speaking - replace TaskCreate.cpp with TaskcreateStub.cpp in your UT project:
CloginActivity.cpp
TaskMock.cpp (if exists)
TaskCreateStub.cpp
TaskCreateStub.cpp should return task-mock - not real task. You need also access to this returned mock-object - so you can set expectations on it.
TaskCreateStub.cpp
// your "real" function here
static TaskMock* taskMockForCreateStub = nullptr;
ITask* createTask() { return taskMockForCreateStub ; }
void setTaskMockForCreateTaskStub(TaskMock* taskMock) { taskMockForCreateStub = taskMock; }
I strongly discourage you from using such linker-level mocking. Use it only for testing legacy code where you cannot redesign it and this might be the only way for using mock...
Related
I am new to google test environment. I have a sample code written in C and want to perform unit test with Google test framework.
Below is the sample code
// My module function (test.c)
void Update_user_value(void)
{
int user_value;
user_value = get_val_module(); /* return a integer value*/
if(user_value == 0x1)
update_user_flag(true);
else
update_user_flag(false);
}
// This function is in the other module(stub.c) , so we can use Mock function
void update_user_flag(bool val)
{
struct *temp;
if(val == true)
{
temp->userflag = 1;
}
else
{
temp->userflag = 0;
}
}
I wan to write a test case for the Update_user_value function (only for test.c). Through this function, i am sending some flag value to other module (update_user_flag) to set the flag.
I have written a simple google test like this
TEST_F(sampletest, setuser_flag_true_testcase)
{
//Get value from module
ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x1)); //Mock function
EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function
Update_user_value();
}
TEST_F(sampletest, setuser_flag_false_testcase)
{
//Get value from module
ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x0)); //Mock function
EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function
Update_user_value();
}
My question: Is this test case is enough to validate the Update_user_value function ?
Also i want to know, EXPECT_CALL() is good to use for setting a value to other module ?
If my understanding is wrong, please suggest me a better test case ?
ON_CALL, EXPECT_CALL are macros designed to be used on mock objects. Usually the use case is as follows:
You create an interface to derive from (it will be mocked in your test).
You pass the mock object (to method or via dependency injection).
You make expectations on this object.
See example:
class Foo {
public:
virtual ~Foo() = default;
virtual int bar() = 0;
};
class FooMock : public Foo {
public:
MOCK_METHOD0(bar, int());
};
bool check_bar_over_42(Foo& foo) {
if (foo.bar() > 42) {
return true;
}
return false;
}
TEST(check_bar_over_42_test, bar_below_42) {
FooMock fooMock{};
EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(41));
ASSERT_FALSE(check_bar_over_42(fooMock));
}
TEST(check_bar_over_42_test, bar_above_42) {
FooMock fooMock{};
EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(43));
ASSERT_TRUE(check_bar_over_42(fooMock));
}
AFAIK there is no way of using EXPECT_CALLs on C-like functions. One approach for your problem would be link-time mocking: given a method get_val_module is defined in a separate library, you can create test-only library with get_val_module that will allow you to return the expected values. In tests you would link against test lib, in production - against the real lib.
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.
Hi I am using test driven development and seem to be in an area I am not familiar. Could you Please check and let me know what changes I should make in my code to make it "unit testable" ?
Code to be tested:
public void PurchaseItemList()
{
//call methods to checkavailablility
If(!productAvailable)
{
purchaseItemEventArgs.IsSuccessfull = false;
}
else
{
purchaseItemEventArgs.IsSuccessfull = true;
// code to update model.
purchaseItemEventArgs.ItemsPurchased = GetItemsPurchased()
}
}
Now the issue I face is that I cannot mock the purchaseItemEventArgs class as it does not implement any interface. I am using moq for testing. Any advise on the code changes to make it unit testable would be very helpfull.
Thanks
Since GetItemsPurchased() is a method of your class, you could make it protected virtual. So you could then define a test class like this:
class TestableMyClass : MyClass{
private Items _items;
public TestableMyClass(Items items) : base() {
_items = items;
}
protected Items GetItemsPurchased(){
return _items;
}
}
And then, in your tests, replace new MyClass by new TestableMyClass(myItems).
This way, your actual GetItemsPurchased() won't be called in your tests, and you can inject the items you want.
I am pulling my hair out with this one. I have looked and cannot find a simple, clear example of creating and using a partial stub with Microsoft Moles. Maybe I'm missing somethimg, or have my code architected poorly, but I can't seem to get this to work.
Here's my class (simplified):
public class AccountService : IAccountService {
private readonly webServiceProxy IExternalWebServiceProxy;
public AccountService(IExternalWebServiceProxy webServiceProxy) {
this.webServiceProxy = webServiceProxy;
}
public List<AccountModel> GetAccounts(string customerId) {
var returnList = new List<AccountModel>();
var xmlResponse = webServiceProxy.GetAllCustomerAccounts(customerId);
var accountNodes = xmlResponse.SelectNodes("//AccountNodes");
if (accountNodes != null)
{
foreach (XmlNode node in accountNodes)
{
var account = this.MapAccountFromXml(node);
if (!string.IsNullOrEmpty(account.AccountNumber))
{
returnList.Add(account);
}
}
}
return returnList;
}
public AccountModel MapAccountFromXml(XmlNode node) {
if (!IsValidAccount(node) {
return null;
}
// This performs a lot of XML manipulation getting nodes based on attributes
// and mapping them to the various properties of the AccountModel. It's messy
// and I didn't want it inline with the other code.
return populatedAccountModel;
{
public bool IsValidAccount(XmlNode node)
{
var taxSelectValue = node.SelectSingleNode("//FORMAT/Field[#taxSelect='1']").First().Value;
var accountStatus = // similar to first line in that it gets a single node using a specific XPath
var maturityDate = // similar to first line in that it gets a single node using a specific XPath
var maturityValue = // similar to first line in that it gets a single node using a specific XPath
return taxSelectValue != string.Empty && taxSelectValue != "0" && (accountStatusValue != "CL" || (maturityDate.Year >= DateTime.Now.AddYears(-1).Year));
}
}
What I want to do is test my GetAccounts() method. I can stub out the IExternalWebServiceProxy call and return fake XML, but I have internal calls happening in my service since my GetAccounts() method calls MapAccountFromXml() which in turn calls IsValidAccount().
Perhaps the solution is to not worry about breaking out the long and involved MapAccountFromXml() and IsValidAccount() code and just put them inline into the GetAccount() call, but I would rather leave them broken out for code readability.
I have my Moles assembly created, and know I can create a stub version of my class like this
var stubWebService = SIExternalWebServiceProxy {
GetAllCustomerAccounts = delegate {
return SomeHelper.GetFakeXmlDocument();
}
}
var stubAccountService = new SAccountService() { callsBase = true; }
My problem is I don't know how to then override the internal calls to MapAccountFromXml and IsValidAccount and I don't want my Unit Test to be testing thos methods, I'd like to isolate GetAccounts for the test. I read somewhere the methods need to be virtual to be overriden in a partial stub, but could not find anything that then showed how to create a stub that overrides a few methods while calling the base for the one I want to test.
Peer put me on the right track, thank you.
It turned out that what I was looking for is called Detours in Moles. Rather than stub an interface using
var stubAccountService = new SIAccountService();
what I needed to do was create an instance of my AccountService and then detour all calls to the methods I wanted to mock, like this
var accountService = new AccountService();
MAccountService.AllInstances.MapAccountFromXmlXmlNode = delegate {
return new AccountModel();
};
The MAccountService is provided by Moles when you Mole your assembly. The only missing piece to this is that for this to work you need to add the following attribute to your test method:
[HostType("Moles")]
This worked for me locally, but in the end I had trouble getting TFS to do automated builds
UPDATE
I just stumbled on another way of doing this, while looking at Rhino Mocks. If the methods in the class being mocked are virtual then you can override them in the mock, like this:
var accountService = new SAccountService();
accountService.MapAccountFromXmlXmlNode = delegate
{
return new AccountModel();
}
Now I can call
accountService.GetMemberAccounts();
and when accountService makes its call to MapAccountFromXml it will be caught by the stub and processed as I deem necessary. No messing with HostType and it works like a charm.
To test methods in you class in issolation you do this with moles by making a mole for the IsValidAccount and MapAccountFromXml methods. Or make a stub implementation with stubs where you let the stub call the orriginal methode using base. Or what I think is a nicer solution, make a test class which overrides the methods you do want to stub (this is the same what a stub would do, except you see all what is happening in your own code):
public class TestHelperAccountService : AccountService {
public override AccountModel MapAccountFromXml(XmlNode node) {
return new AccountModel(){
//Accountmodelstub
};
{
public override bool IsValidAccount(XmlNode node)
{
return true;
}
}
This way you can do your test for the GetAccount method on your TestHelperAccountService class where you GetAccount method runs in full issolation. You can do the same for the methods like MapAccountFromXml to test them seperatly.
I have a question about testing.
I have a class that returns anomalies. in this class I have two different method that simply returns two different types of anomalies and one that return all anomalies (of both types)
this is the example code:
public interface IAnomalyService
{
IList<Anomaly> GetAllAnomalies(object parameter1, object parameter2);
IList<Anomaly> GetAnomalies_OfTypeA(object parameter1);
IList<Anomaly> GetAnomalies_OfTypeB(object parameter2);
}
public class AnomalyService : IAnomalyService
{
public IList<Anomaly> GetAllAnomalies(object parameter1, object parameter2)
{
var lstAll = new List<Anomaly>();
lstAll.AddRange(GetAnomalies_OfTypeA(parameter1));
lstAll.AddRange(GetAnomalies_OfTypeB(parameter2));
return lstAll;
}
public IList<Anomaly> GetAnomalies_OfTypeA(object parameter1)
{
//some elaborations
return new List<Anomaly> { new Anomaly { Id = 1 } };
}
public IList<Anomaly> GetAnomalies_OfTypeB(object parameter2)
{
//some elaborations
return new List<Anomaly> { new Anomaly { Id = 2 } };
}
}
class Anomaly
{
public int Id { get; set; }
}
I've created the tests for the two method that retrieve the anomalies of type A and type B (GetAnomalies_OfTypeA and GetAnomalies_OfTypeB).
Now I want to test the function GetAllAnomalies but I'm not sure what I have to do.
I think I have to way for testing it:
1) declare GetAnomalies_OfTypeA and GetAnomalies_OfTypeB in class AnomalyService as virtual, make a mock of the Class AnomalyService, and using Moq I can set CallBase as true and mock the two method GetAnomalies_OfTypeA and GetAnomalies_OfTypeB.
2)move the method GetAllAnomalies in another class called AllAnomalyService (with interface IAllAnomalyService) and in its constructor I will pass an interface of IAnomalyService and after I can test the GetAllAnomalies mocking the IAnomalyService interface.
I'm new at unit testing, so I don't know which solution is better, if is one of the mines or another one.
Can you help me?
thank you
Luca
Mocking is a good tool when a class resists testing. If you have the source, mocking is often not necessary. Try this approach:
Create a factory which can return AnomalyServices with various, defined anomalies (only type A, only type B, both, none, only type C, ...)
Since the three types are connected in some way, you should check all three in each test. If only anomalies of type A are expected, you should check that GetAllAnomalies returns the same result as GetAnomalies_OfTypeA and GetAnomalies_OfTypeB returns an empty list.