c++ Google test (gtest): how to create custom asserts and expects? - c++

I am using gtest to create unit tests to my c++ program. In my tests I have to write a lot of checks like this:
ASSERT_TRUE(myObject.IsValid());
EXPECT_EQ(myObject.GetSomeAttribute(), expectedValue);
I have to write both checks because if I omit the ASSERT_TRUE and myObject happened to be not valid, than myObject.GetSomeAttributre() call crashes. That's not good even in tests.
What I want is to write something like:
EXPECT_XXX_EQ(myObject.GetSomeAttribute(), expectedValue);
This line of code should do approximately the same as the original two lines (with optional bonus that if myObject is not valid, this will be reported, GetSomeAttribute() would not be called, but the test will continue running).
How can I write such custom assert/expect?

From the Advanced Guide, we can see that there are a couple ways we could do this.
The easiest way is by using assertions in a subroutine:
template<typename T>
void AssertAttributeEquals(MyObject const& obj, T value) {
ASSERT_TRUE(obj.IsValid());
// googletest has the assumption that you put the
// expected value first
EXPECT_EQ(value, obj.GetAttribute());
}
And you can call it like so:
AssertAttributeEquals(myObject, expectedValue);
Although you may want to use SCOPED_TRACE to get a better message on failure:
{
SCOPED_TRACE("whatever message you want");
AssertAttributeEquals(myObject, expectedValue);
}
Alternatively, you can use a function that returns an AssertionResult:
template<typename T>
::testing::AssertionResult AttributeEquals(MyObject const& obj, T value) {
if (!obj.IsValid()) {
// If MyObject is streamable, then we probably want to include it
// in the error message.
return ::testing::AssertionFailure() << obj << " is not valid";
}
auto attr = obj.GetAttribute();
if (attr == value) {
return ::testing::AssertionSuccess();
} else {
return ::testing::AssertionFailure() << attr << " not equal to " << value;
}
}
This can be used like so:
EXPECT_TRUE(AttributeEquals(myObject, expectedValue));
This second technique has the benefit of producing nice error messages even if you don't use SCOPED_TRACE

Related

How to return null from a function whose return type is map in Visual C++?

I want to return null data from a function that return type is map.
Here is my code.
map<string, string> something_to_do(string something) {
// something to do..
// if above code is something wrong, it should return null.
return null;
}
But, there seems to be no type casting to return null in map library.
How can I do it?
(I'm sorry my awful English..)
as an alternative you can in C++17 use instead std::optional
std::optional<std::map<string,string>> something_to_do(string something) {
std::map<std::string,std::string> yourmap;
yourmap["a"] = "b";
...
return yourmap;
// or
// return std::null_t;
}
...
auto d = something_to_do(something);
if (d)
{
auto& m = d.value();
std::cout << m["a"] << std::endl;
}
I think the functionality you are looking for would be better handled by throwing an exception.
That way you can proceed as normally, but if something goes wrong like you allude to in your comment, then you want to throw an exception and have any client code handle the exception accordingly. See this SO post.
It allows you to write straight-forward code without having custom types to return for every possible situation of your running code. It also eliminates the need to check for certain values being returned just to handle any errors.
To call the function and handle the error, you would simply wrap the method call in a try-catch block:
from #nsanders' orginal answer
try {
compare( -1, 3 );
}
catch( const std::invalid_argument& e ) {
// do stuff with exception...
}
If the function returns a map you must return a map - you cannot return nullptr (an empty map, sure, but that's as close as you'll get). Maybe you are looking for std::optional so you can have your function return an optional map that may or may not be there?

Getting rid of an ugly C construct

I have inherited a (large) piece of code which has an error tracking mechanism where they pass in a boolean variable to all the methods they call and on errors at various stages of execution the method is stopped and returns, sometimes a default value.
Something like (BEFORE):
#include <iostream.h>
int fun1(int par1, bool& psuccess)
{
if(par1 == 42) return 43;
psuccess = false;
return -1;
}
int funtoo(int a, bool& psuccess)
{
int t = fun1(a, psuccess);
if(!psuccess)
{
return -1;
}
return 42;
}
void funthree(int b, bool& psuccess)
{
int h = funtoo(b, psuccess);
if(!psuccess)
{
return;
}
cout << "Yuppi" << b;
}
int main()
{
bool success = true;
funthree(43, success);
if(!success)
{
cout<< "Life, universe and everything have no meaning";
}
}
Please note, that this is a mixture of C and C++ code, exactly the way the project is in.
Now, comes a piece of C magic: "someone" somewhere defined a macro:
#define SUCCES_OR_RETURN if(!psuccess) return
And the program above becomes (AFTER):
#include<iostream.h>
int fun1(int par1, bool& psuccess)
{
if(par1 == 42) return 43;
psuccess = false;
return -1;
}
int funtoo(int a, bool& psuccess)
{
int t = fun1(a, psuccess);
SUCCES_OR_RETURN -1;
return 42;
}
void funthree(int b, bool& psuccess)
{
int h = funtoo(b, psuccess);
SUCCES_OR_RETURN ;
std::cout << "Yuppi" << b;
}
int main()
{
bool success = true;
funthree(43, success);
if(!success)
{
cout<< "Life, universe and everything have no meaning";
}
}
The question: I am wondering if there is a nicer way to handle this kind of error tracking or I have to live with this. I personally don't like the abuse of the C macro SUCCES_OR_RETURN ie. that once it is called with a parameter, and in other cases it is called without, feels like a real return statement, but I did not find any better solutions to this ancient design.
Please note that due to platform restrictions we have several restrictions, but regardless of it I am willing to hear opinions about these two:
throwing exceptions. The code is a mixture of C and C++ functions calling each other and the compiler sort of does not support throw (accepts in the syntax but does nothing with it, just a warning). This solution is sort of the standard way of solving this problem in a C++ environment.
C++11 features, this goes to a tiny embedded platform with an obscure and ancient "almost" C++ compiler which wasn't made to support the latest C++ features. However for future reference I am curios if there is anything C++11 offers.
template magic. The compiler has problems understanding complex templated issues, but again I am willing to see any solutions that you can come up with.
Edit
Also, as #BlueMoon suggested in the commend, creating a global variable is not working since at a very beginning of the function chain calling the success variable is a member variable of a class, and there are several objects of this class created, each of them needs to report its success status :)
There's a great breakdown of hybrid C and C++ error handling strategies here:
http://blog.sduto.it/2014/05/a-c-error-handling-style-that-plays.html
To quote the linked article, your options largely boil down to:
Return an error code from functions that can fail.
Provide a function like Windows's GetLastError() or OpenGL's glGetError() to retrieve the most recently occurring error code.
Provide a global (well, hopefully, thread-local) variable containing the most recent error, like POSIX's errno.
Provide a function to return more information about an error, possibly in conjunction with one of the above approaches, like POSIX's strerror function.
Allow the client to register a callback when an error occurs, like GLFW's glfwSetErrorCallback.
Use an OS-specific mechanism like structured exception handling.
Write errors out to a log file, stderr, or somewhere else.
Just assert() or somehow else terminate the program when an error occurs.
It seems like the author of the code you have inherited picked a rather strange way, passing a pointer to a boolean [sic] for the function to work with seems rather unusual.
The article has some great examples, personally I like this style:
libfoo_widget_container_t container = NULL;
libfoo_error_details_t error = NULL;
if (libfoo_create_widgets(12, &container, &error) != libfoo_success) {
printf("Error creating widgets: %s\n", libfoo_error_details_c_str(error));
libfoo_error_details_free(error);
abort(); // goodbye, cruel world!
}
Here you get a bit of everything, passed in pointer to error type, a comparison against a success constant (rather than 0|1, a painful dichotomy between C and the rest of the world!).
I don't think it would be too much of a push to say that your macro could rather better be implemented with a goto, in any case, if a function is calling SUCCES_OR_RETURN more than once, it might be a clue that the function is doing too much. Complex cleanup, or return might be a code smell, you can read more here http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/
I have seen this style of error handling before. I call it error-oblivious manual pseudo-exceptions.
The code flow is mostly error-oblivious: you can call 3 functions in a row with the same error flag, then look at the error flag to see if any errors have occurred.
The error flag acts as a pseudo-exception, where once set we start "skipping" over normal code flow, but this is done manually instead of automatically.
If you do something and do not care if an error occurs, you can just drop the error produced and proceed on.
The ICU library handles errors in a similar way.
A more C++1y way to do this while minimizing structural differences would be to modify code to return an expected object.
An expected<T, Err> is expected to be a T, and if something went wrong it is instead an Err type. This can be implemented as a hybrid of boost::variant and C++1y's std::optional. If you go and overload most arithmetic operations on expected< T, Err > + U to return expected< decltype( std::declval<T&>() + std::declval<U>(), Err > and did some careful auto, you could allow at least arithmetic expressions to keep their structure. You'd then check for the error after the fact.
On the other hand, if the error return values are predictable based on their type, you could create a type that when cast to a given type produced an error value. Modify functions returning void to return an error object of some kind while you are at it. And now every function can
if (berror) return error_flag_value{};
which at least gets rid of that strange ; or -1; issue.
If you want to go full C++, the answer would be changing the "invalid return values" for exceptions...
#include <iostream>
#include <exception>
using std::exception;
struct error : exception { const char* what() const throw() override { return "unsuccessful"; } };
int fun1(int par1) {
if( par1 == 42 ) return 43;
throw error();
}
int funtoo(int a) {
fun1(a);
return 42;
}
void funthree(int b) {
funtoo(b);
std::cout << "Yuppi " << b << "\n";
}
int main() {
try {
funthree(42);
} catch(exception& e) {
std::cout << "Life has no meaning, because " << e.what() << "\n";
}
}
This prints Yuppi 42 (if you change the call funthree(42) for funthree(43) it prints Life has no meaning, because unsuccessful...)
(live at coliru)

C++ Scope of Static Variable In a Static Member Function

I have a simple object which does some parsing. Inside, there is a parse function, containing a static variable that is used to limit number of error messages to print to the user:
struct CMYParsePrimitive {
static bool Parse(const std::string &s_line)
{
// do the parsing
static bool b_warned = false;
if(!b_warned) {
b_warned = true;
std::cerr << "error: token XYZ is deprecated" << std::endl;
}
// print a warning about using this token (only once)
return true;
}
};
Now these parse primitives are passed in a typelist to a parser specialization. There is some other interface which tells parser which token types should be parsed using which parse primitives.
My issue is that the warning should be displayed up to once per application run. But in my case, it is sometimes displayed multiple times, seems to be per parser instance rather than application instance.
I'm using Visual Studio 2008, I imagine this might be some bug or a deviation from the standard? Does anyone have any idea as to why this happens?
I failed to notice that the function is also a template. My bad. It is instantiated twice in the code with different parameters - hence the warning is sometimes printed twice. The real code looks more like this:
struct CMYParsePrimitive {
template <class CSink>
static bool Parse(const std::string &s_line, CSink &sink)
{
// do the parsing, results passed down to "sink"
static bool b_warned = false;
if(!b_warned) {
b_warned = true;
std::cerr << "error: token XYZ is deprecated" << std::endl;
}
// print a warning about using this token (only once)
return true;
}
};
So then there are e.g. CMYParsePrimitive::Parse<PreviewParser>::b_warned, which can print the warning once when used by PreviewParser, and then also CMYParsePrimitive::Parse<Parser>::b_warned which can print the warning when used by Parser.

Stop evalulate operator<<

I am trying to do a simple logging library only for my own. I know there exists several once, but I have not found any header-only, small and very "c++" like logging library which fits into my application.
Currently I have the following syntax:
logger << debug << "A debug message" << end; //debug and end is my custom manipulators
I have implemented all necessary operator<< and it works great, specially when it have backward compatibility with std::ostream. But I wonder, just for efficiency if it is a why to stop evaluate anything if some message should not be logged (after debug in the example)? Making everything after the severity manipulator "disappear"?
Just now do I have the following code in short:
template <typename Type>
Logger & Logger::operator<<(const Type & message)
{
if(this->get_message_level() <= this->get_severity())
{
BOOST_FOREACH(std::ostream* stream, this->_sinks)
{
*stream << message;
}
}
return *this;
}
Logger & Logger::operator<< (Logger & (*pf)(Logger&))
{
return pf(*this);
}
Logger & debug(Logger& logger)
{
logger.lock();
logger.set_severity(7);
//...
return logger;
}
Logger & end(Logger& logger)
{
logger << std::endl;
logger.unlock();
return logger;
}
Thanks in advance.
You could do something as simple as
extern "C" bool want_log;
#define LOG(Arg) do { if (want_log) \
cout << __FILE__ << ":" << __LINE__ ": " << Arg << endl; } while(0)
and use it as LOG("x=" << x)
It can be a bit tricky, depending on what compromizes you're willing to
accept in the syntax. If you really want to support everything that
outputting to an ostream does, then the best you can do (as far as I
know) is a wrapper class, along the lines of:
class Logger
{
std::ostream* myDest;
public:
// Appropriate constructors...
template<typename T>
Logger& operator<<( T const& obj )
{
if ( myDest != NULL )
(*myDest) << obj;
return *this;
}
};
If logging is turned off (Logger::myDest == NULL), none of the
conversion code will execute, but you'll still evaluate each of the
arguments. In my experience, this is not usually an issue, since most
of the arguments are either string literals or a simple variable, but
it's not a total 0 cost. It also has the potential disadvantage that
the propagated type is not std::ostream& (although I've never found
this to be a problem in practice).
A somewhat tricker solution would be to use a macro along the lines of:
#define logger loggerInstance != NULL && (*loggerInstance)
This will still allow most of the actual uses with the same syntax
(because the && operator has very low precedence), but could fail in
cases where someone has tried to be too clever, and embedded the logging
output in a more complicated expression. In addition to not doing the
conversions, the arguments are not even evaluated if logging is turned
off.
Finally, if you accept a different syntax, you can write something like:
#ifndef NDEBUG
#define LOG(argList) logger << argList
#else
#define LOG(argList)
#endif
This requires the user to write LOG("x = " << x), instead of log <<
"x = " << x, and requires recompiling if you want to turn logging on,
but it is the only solution I know which has absolute 0 cost if logging
is turned off.
In my experience, most applications can support the first solution; in a
very few cases, you might want to use the second; and I've never seen an
application where performance required the third.
Note that even with the first, you'll probably want to use a macro to
get the logger instance, in order to automatically insert __FILE__ and
__LINE__, and that in the second, you'll probably still want to use a
wrapper class, in order to ensure a flush in the destructor; if the
application is multithreaded, you'll want the wrapper in all cases, in
order to make the entire sequence of output atomic.
You could check for the severity in the Logger & Logger::operator<< (Logger & (*pf)(Logger&)) operator and just return an "empty" logger that doesn't print anything in that case:
class EmptyLogger : public Logger {
template <typename Type>
Logger & Logger::operator<<(const Type & message) { return *this; }
};
EmptyLogger empty; // Can be global/static, it won't cause any race conditions as it does nothing
Logger & Logger::operator<< (Logger & (*pf)(Logger&))
{
if (logger.get_severity() < 5) // Replace with a proper condition
return empty;
return pf(*this); // What does pf() do? Aren't you returning reference to a temporary object?
}
Take a look at this article in dr dobbs about logging in c++:
http://drdobbs.com/cpp/201804215?pgno=2
This page addresses your particular concern but I'd recommend reading the whole article.
I implemented a logging system based on this article and was really pleased with it.

Google Test C++: Is there a way to read the current console output in a test?

Let us assume I have a to be tested class that has the following method:
void
MyClass::sayHello()
{
std::cout << "Hello";
}
Now, within my google test I would like to verify that this output has been made. What would be the lastConsoleOutput equivalent be as used in my pseudo code below?
// Tests if sayHello() outputs Hello
TEST(MyClassTest, sayHello)\
{
EXPECT_EQ(lastConsoleOutput,"Hello");
}
Thank you for any feedback!
In this case I would avoid redirecting or testing for values in stdout or stderr, since the access to those streams is not threads-safe in a way that output buffer may not be appended and flushed as possibly predicted.
From a testing perspective I would suggest refactoring the method to be stateless and keep the state (a.k.a. std::cout) somewhere else. In your example you start testing behavior of an external API and not the actual modification in your object.
class MyClass {
std::sstream state;
public:
void print(){ std::cout << state.str(); } // no need to test this method, only external API
void changeState() {
state << "Hello" << std::endl; // this should be tested
}
}
In your testing code you can now easily perform the test using
// Tests if sayHello() outputs Hello
TEST(MyClassTest, sayHello)
{
myClass.changeState();
EXPECT_STREQ(myClass.state.str().c_str(),"Hello");
}
I avoid having code like your sayHello() method. I would refactor it to something like:
void MyClass::sayHello(std::ostream& out) {
out << "Hello";
}
Then the test method would be like this:
TEST(MyClassTest, sayHello) {
MyClass c;
std::stringstream strm;
c.sayHello(strm);
EXPECT_STREQ("Hello", strm.str.c_str());
}