I'd like to write a unit-test for a method that prints to the standard output.
I have already changed the code so it prints to a passed-in File instance instead that is stdout by default. The only thing I am missing is some in-memory File instance that I could pass-in. Is there such a thing? Any recommendation? I wish something like this worked:
import std.stdio;
void greet(File f = stdout) {
f.writeln("hello!");
}
unittest {
greet(inmemory);
assert(inmemory.content == "hello!\n")
}
void main() {
greet();
}
Any other approach for unit-testing code that prints to stdout?
Instead of relying on File which is quite a low level type, pass the object in via an interface.
As you have aluded to in your comment OutputStreamWriter in Java is a wrapper of many interfaces designed to be an abstraction over byte streams, etc. I'd do the same:
interface OutputWriter {
public void writeln(string line);
public string #property content();
// etc.
}
class YourFile : OutputWriter {
// handle a File.
}
void greet(ref OutputWriter output) {
output.writeln("hello!");
}
unittest {
class FakeFile : OutputWriter {
// mock the file using an array.
}
auto mock = new FakeFile();
greet(inmemory);
assert(inmemory.content == "hello!\n")
}
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 have create an interface (here's an example):
class DataStream
{
virtual std::string read(std::string terminator) = 0;
virtual size_t write(std::string data) = 0;
};
For which there exists a concrete implementation, such as:
class SerialDataStream : public DataStream
{
public:
// NOTE: This constructor will throw an exception if the
// serial port cannot be opened.
SerialDataStream(string port, int baudrate);
std::string read(std::string terminator);
size_t write(std::string data);
}
And the interface is used, for example:
class SomeThing
{
public:
SomeThing(std::shared_ptr<DataStream> stream);
}
Using GoogleMock, testing the SomeThing class is fairly straight forward, all you need to do is create a mock implementation for the interface, for example:
class MockDataStream : public DataStream
{
public:
MOCK_METHOD1(read, size_t(std::vector<uint8_t>&));
MOCK_METHOD1(write, size_t(std::vector<uint8_t>&));
}
Where the test would look something like this:
std::shared_ptr<MockDataStream> mock_stream(nullptr);
mock_stream = std::make_shared<MockDataStream>();
EXPECT_CALL(*mock_stream, write("START")).Times(AtLeast(1));
EXPECT_CALL(*mock_stream, read("\n")).Times(AtLeast(1));
SomeThing some_thing = SomeThing(mock_stream);
Which is pretty cool as it easily allows me to unittest how the SomeThing class uses the DataStream interface.
However, there also exists some code whose job it is to create new (concrete) DataStream objects and I'm finding using GoogleMock to test this a little more tricky. For example, here is a snippet of some code that needs to be tested:
std::shared_ptr<DataStream> datastream(nullptr);
// Try and open the serial port:
try
{
std::shared_ptr<SerialDataStream> serialstream =
std::make_shared<SerialDataStream>("/dev/tty99", 115200);
}
catch (...)
{
// Returns a nullptr
return datastream;
}
// Check if there is a known device on the other end:
datastream = std::static_pointer_cast<DataStream>(serialstream);
if (!device_is_connected(datastream))
{
datastream = nullptr;
}
return datastream;
I'm struggling to find an effective method to test this code with GoogleMock:
I would like to mock the constructor (of SerialDataStream) so it throws an exception and the failure path is executed as expected.
I would like to test the successful path where the private API "device_is_connected" uses the newly created datastream object.
Is it the case that I have no option other than to create a fake SerialDataStream implementation and use dependency injection to test the code which creates concrete DataStream objects?
If this is the case, I'll just have to make the API "device_is_connected" public so I can simply test it with a mock implementation of the interface (as above) to test, for example:
datastream.write("DISCOVER");
string response = datastream.read("\n");
if (discovery_ok(response))
{
// do stuff
}
I'm fairly certain I've answered my own question and will have no option but to fake the SerialDataStream class and use dependency injection, and make private APIs public and simply test them via GoogleMock, but I'm open to suggestions if there's a better way I could/should be doing things here.
Looking at the code snipped you provided, I found myself asking:
What exactly should the function do? It seems like it
(1) creates a SerialDataStream and
(2) checks if a device is connected.
You may could break the function into two (individually testable) parts.
Still there is the question on how to handle the std::shared_ptr<SerialDataStream> serialstream = std::make_shared<SerialDataStream>("/dev/tty99", 115200); - at some point you will need to tackle the (hidden) new there.
And I agree with you - dependency injection might be the solution there. Turning whatever class or function ends up responsible for creating into a template class/function would allow to write you (e.g.)
template<typename T>
std::shared_ptr<DataStream> createDatastream()
{
std::shared_ptr<DataStream> datastream(nullptr);
std::shared_ptr<T> datastream = std::make_shared<T>("/dev/tty99", 115200);
return datastream;
}
And then instantiate the class/function with SerialDataStream in your application, while using a MockDataStream to test the function(s).
I wasn't sure of the best name for this thread, but I'm trying to refactor some code and remove some decoupling. I am forced to use Visual Studio 2005 C++ without boost, don't ask... (So not c++11, or newer)
I have a protocol that receives messages, and the protocol contains a parser and processor. Parser extracts the information out of the message, and populates a structure. The structure is then passed into the processor to take further action on it.
class Protocol
{
Parser parser;
Processor processor;
public:
Protocol() : parser(processor)
{
}
handleMessage(Message& message)
{
ParsedData parsedData;
parser.parse(message, parsedData);
}
}
class Parser
{
Processor processor;
public:
Parser()
{
}
Parser(Processor& p) : processor(p)
{
}
parse(Message& message, ParsedData& parsedData)
{
if(message.type == "whatever")
{
parseLevel2(message.message, parsedData);
}
//else if Other message types
}
parseLevel2(MessageLevel2& message, ParsedData& parsedData)
{
//Keep going down the rabbit hole, but for simplicity it ends here
parsedData.blah = "some data";
processor.ProcessBlahMessage(parsedData);
}
}
class Processor
{
public:
Processor()
{
}
ProcessBlahMessage(ParsedData& parsedData)
{
//Do logic
}
}
I was hoping to strip the Processor from the Parser so it became more like this...
class Protocol
{
Parser parser;
Processor processor;
public:
Protocol() : parser(processor)
{
}
handleMessage(Message& message)
{
ParsedData parsedData;
parser.parse(message, parsedData); //This will not call the processor from within it
processor.process(parsedData); //This is the new
}
}
The only issue that is preventing me from doing this is I will have to have a bunch of if statements in the process method.
process(ParsedData& parsedData)
{
if(parsedData.type == "blah")
{
ProcessBlahMessage()
}
else if(parsedData.type == "grah")
{
ProcessGrahMessage()
}
//etc...
}
My question is how do I avoid all those if statements where I'm essentially just parsing it again? If I give the parsedData a function pointer, or lambda then I'm still going to need a reference to the processor in the parser.
you can try this:
1) in your parsed data instead of .blah and .grah store vector<void*>
2) assuming create new blah object ( or whatever message type is) and put pointer to it into vector (using type as index).
3) in your processor store vector of handlers. pass into processor type along with parsed data, so you can call correct handler for correct pointer
4) in your handler cast void* to blah* (or whatever real type is)
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...
I am trying to test a document reader using Google Test.
My code is organized as follow: there is a Document class which opens the file. A document contains one or more Element, which is a struct with a pointer (field) to a wstring and value.
Obviously I would like to open the file just once and then cycle though the various Elements.
class DocumentTest : public ::testing::Test {
protected:
virtual void SetUp() {
string path = "path/to/file";
Document doc;
doc.Open(path);
}
Element* el;
el = doc.Read();
};
TEST_F(DocumentTest, ReadTest) {
while (file has still elements) {
wchar_t* expectedField = L"expectingThis";
wchar_t* readString = el->field;
EXPECT_EQ(expectedField,readString);
}
but this is clearly not working. Where should I declare my init code?
https://github.com/google/googletest/blob/main/docs/advanced.md
In general googletest allows three different modes of resource management:
SetUp and TearDown() (run before and after each test function)
SetUpTestCase() and TearDownTestCase() (run before and after each class, or "Case")
The Environment class which is run before/after the first and last test, respectively.