I am facing problems in writing unit tests to C functions which involve IO operation. For example, below is the code I wrote to get an input string from the user from console. I do not know as to how to automate testing user input using getchar() function.
char * GetStringFromConsole()
{
char *strToReturn = NULL;
int len = 128;
strToReturn = (char*)malloc(len);
if (strToReturn)
{
int ch;
char *ptr = strToReturn;
int counter = 0;
for (; ;)
{
ch = getchar();
counter++;
if (counter == len)
{
strToReturn = realloc(strToReturn, len*=2 );
ptr = strToReturn + counter-1;
}
if ((ch != EOF) && (ch != '\n') && (counter < len))
{
*ptr++ = ch;
}
else
{
break;
}
}
*ptr = '\0';
}
return strToReturn;
}
Unit testing only requires "cut-planes" or boundaries at which testing can be done. It is quite straightforward to test C functions which do not call other functions, or which call only other functions that are also tested. Some examples of this are functions which perform calculations or logic operations, and are functional in nature.
A unit is simply a small piece of code for any single function. So when we test those units, it is called a unit test. The unit test is a short script or piece of code designed to verify the behavior of a particular unit independently to produce a pass or fail result. Unit Testing is performed during the application development phase.
You can write and run your C++ unit tests by using the Test Explorer window. It works just like it does for other languages. For more information about using Test Explorer, see Run unit tests with Test Explorer.
You define and run tests inside one or more test projects. You create the projects in the same solution as the code you want to test. To add a new test project, right-click on the Solution node in Solution Explorer and choose Add > New Project. In the left pane, choose Visual C++ Test. Then, choose one of the project types from the center pane.
Mock getchar
:
Utilizing preprocessor, e.g. in your test file.
#define getchar mock_getchar
#include "GetStringFromConsole.h"
...
const char* mock_getchar_data_ptr;
char mock_getchar()
{
return *mock_getchar_data_ptr++;
}
...
// in test function
mock_getchar_data_ptr = "hello!\n";
YourAssertEquals("hello", GetStringFromConsole());
Substitute symbol for the linker(harder, in my opinion), e.g. define your own getchar
somewhere in your source .c files instead of linking to a stdlib(e.g. msvcrt on windows)
Modify function under test to accept a function returning char
, best choice(IMHO) - no conflicts with stdlib. And setup a test by passing a thingy like mock_getchar
from point 1 in test code.
typedef char (*getchartype)();
char * GetStringFromConsole(getchartype mygetchar)
{
...
c = mygetchar()
For points 1 and 2 I'd propose to use your own function instead of getchar
(e.g. mygetchar
) - this way you could mock/substitute it without facing conflicts with std includes/libs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With