I have come to something of a crossroads. I recently wrote a 10,000 line application with no TDD (a mistake I know). I definitely ran into a very large amount of errors but now I want to retrofit the project. Here is the problem I ran into though. Lets take a example of a function that does division:
public int divide (int var1, int var2){
if (var1 == 0 || var2 == 0)
throw new RuntimeException("One of the parameters is zero");
return var1 / var2;
}
In this situation I'm throwing a runtime error so that I can fail and at least find out that my code is broke somewhere. The question is 2 fold. First, am I making the correct use of the exceptions here? Secondly how do I write a test to work with this exception? Obviously I want it to pass the test but in this case it's going to throw an exception.
Not too sure how one would work that out. Is there a different way that this is generally handled with TDD?
Thanks
First, your first argument (the numerator) being zero probably shouldn't cause an exception to be thrown. The answer should just be zero. Only throw an exception when a user tries to divide by zero.
Second, there are two ways (using JUnit) to test that exceptions are thrown when they should be. The first "classic" method:
#Test
public void testForExpectedExceptionWithTryCatch()
throws Exception {
try {
divide (1, 0);
fail("division by zero should throw an exception!");
} catch (RuntimeException expected) {
// this is exactly what you expect so
// just ignore it and let the test pass
}
}
The newer method in JUnit 4 uses annotations to cut down on the amount of code you need to write:
#Test(expected = RuntimeException.class)
public void testForExpectedExceptionWithAnnotation()
throws Exception {
divide (1, 0);
}
Here, because we added (expected = RuntimeException.class) to the annotation, the test will fail if the call to divide doesn't throw a RuntimeException.
To answer your first question:
If it's quite likely the denominator argument to divide will be 0 then you shouldn't be using exception handling to trap the error. Exceptions are expensive and shouldn't be used to control program flow. So you should still check, but return an error code (or use a nullable type as the return value) and your calling code should check on this and handle it appropriately.
public int? divide (int var1, int var2)
{
if (var2 == 0)
{
return null; // Calling method must check for this
}
return var1 / var2;
}
If zeros are truly the exception - e.g. there should be no way that they can be passed - then do as you do now.
To answer your second question:
In your test methods that check the failure code you need an exception handler:
try
{
divide (1, 0);
// If it gets here the test failed
}
catch (RuntimeException ex)
{
// If it gets here the test passed
}
I am not answering your main question.
I would suggest using ArgumentException instead of RuntimeException.
EDIT: I am assuming .net :)
Your question was language-agnostic, so my answer might not apply, but NUnit in .NET (and I believe JUnit too) have a specific notation for testing exceptions. In NUnit, your test would look like this:
[Test]
[ExpectedException(typeof(RuntimeException))]
public void DivideByZeroShouldThrow()
{
divide(1,0);
}
The test will fail if the right type of exception is not thrown during the execution.
The try/catch approach works too, and has its advantages (you can pinpoint exactly where you expect the exception to occur), but it can end up being pretty tedious to write.
The first question is answered well by ChrisF and Bill the Lizard.
I just want to add an alternative to the exception test, with C++11 you can use a lambda directly in your test.
Assert::ExpectException<std::invalid_argument>([] { return divide(1,0); }, "Division by zero should throw an exception.");
This is equivalent to:
try
{
divide(1,0);
Assert::Fail("Division by zero should throw an exception.");
}
catch(std::invalid_argument)
{
//test passed
}
Related
I have a C++ class I am attempting to test with GMock. I have the following mock class:
class MyTestMock
{
public:
MOCK_METHOD1(myCoolMethod, int(const char*));
MOCK_METHOD1(myCoolMethod, int(string));
}
Then in my test the following happens:
MyTestMock myMock;
if ( myMock.myCoolMethod("stuff") )
{
// Stuff I don't care about, don't want to execute
}
if ( myMock.myCoolMethod("moarStuff") )
{
// More stuff I don't care about, don't want to execute
}
if ( myMock.myCoolMethod("foo") )
{
// This I care about and want to execute
}
What I would like to do is allow the first two calls to be uninteresting calls that return the default for integers, 0, while I set up a specific expectation on the third call to return 1. This was my attempt to do so:
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));
However, this ends up making the test fail. If I do this instead:
EXPECT_CALL(myMock, myCoolMethod(Matcher<const char *>(_))).WillRepeatedly(Return(0));
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));
my test passes fine. I am attempting to make unit testing as painless as possible on an old, massive, monolithic-style codebase, so I'd really like to not need the extra magic line to tell it to return the default value. Any ideas on how I can do this with just the one expectation without tanking my test?
I guess my answer is not very "expected" for testing "an old, massive, monolithic-style codebase" with possible huge numbers of such CoolMethods..., but, unfortunately this is how google-mock works. As you can read in their FAQ:
Having an ON_CALL in the set-up part of a test doesn't mean that the
calls are expected. If there's no EXPECT_CALL and the method is
called, it's possibly an error. If we quietly let the call go through
without notifying the user, bugs may creep in unnoticed.
The same is with "default" ON_CALL - I mean when you did not write explicitly ON_CALL because default value for a type (in your case 0 for int) is perfectly OK.
My advice is to always put such general expectation in SetUp function of your test suite - this way your test cases are not overloaded with many magic expectations:
class MyTestSuite : public ::testing::Test
{
protected:
MyTestMock myMock;
void SetUp() override
{
EXPECT_CALL(myMock, myCoolMethod(Matcher<const char *>(_))).WillRepeatedly(Return(0));
}
};
This way you have "annoying" lines only in one place, and your test cases are "clear":
TEST_F(MyTestSuite, shallDoSomethingWhenCoolMethodAcceptsFoo)
{
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));
}
TEST_F(MyTestSuite, shallDoSomethingElseWhenCoolMethodAcceptsMoarStuff)
{
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("moarStuff"))).WillOnce(Return(1));
}
I am looking for someones opinion about the usage of std::logic_error instead of using a complicated list of nested if/elseif return true/false.
I would like to move from a lot of similar function like the one below
bool validate_data(){
std::vector<int> v;
//fill with data
if( v.find(10) == v.end() ){
return false;
}
// other checks that return false
}
to
bool validate_data(){
std::vector<int> v;
//fill with data
if( v.find(10) == v.end() ){
throw std::logic_error("error message");
}
// other checks that return false
}
and call all this list of functions in a single try-catch block.
Since it is a derived from std::exception probably I don't know if it is a good idea.
Is anyone using like the example below?
Thanks a lot
AFG
You should only use exceptions for exceptional circumstances. Using (and checking) return values is far more efficient when the chances of it being true or false are non-trivial. Exceptions are more efficient only when the chance of throwing is so small as to out-weigh the cost of the return-value check.
So if the chances of invalid data are very very low, then go with exceptions. Otherwise, the current solution should not only be fine, but slightly more efficient as well (As throwing and handling is relatively expensive).
Only use exceptions for exceptional situations.
Is not finding the value 10 an exceptional situation? Or is it just a normal situation?
Renaming your method from validate_data to is_data_valid makes it much clearer. If the method returns true, it's valid. If it returns false, it isn't. No need to use exceptions for this.
Since your function is called validate_data() I'd only throw an exception if there is any internal error within the function and use true or false to indicate that the function did validate the input, but it was either valid (return true) or invalid (return false).
This will not prevent you from having multiple if() else if() else constructs but it will make the code cleaner and easier to distinguish if the data were invalid or an internal error happened.
try {
bool valid = validate_data(foo);
/* process data or break if invalid */
} catch (std::exception &ex) {
/* internal error happened */
}
as you can see it will make your code longer, IMHO cleaner.
I have read answers to following questions ->
c++ exception : throwing std::string
c++ Exception Class Design
My requirement is to catch exceptions and allow a mechanism to reformat the error messages and then re-throw the exceptions.
So I thought of writing my exception class which will provide a method to reformat the error message at various catch points.To make reformatting easy, I'm embedding a string object in myexception_base class.
I have also referred to this article -> http://www.boost.org/community/error_handling.html which clearly says not to embed string objects in exception classes.
The article also has a quote "Peter Dimov makes an excellent argument that the proper use of a what() string is to serve as a key into a table of error message formatters." but it does not elaborate on it any further.
I have written the code as given below and my questions are -
1) If I don't embed a string object in my exception class, it will make it difficult to reformat the what messages. Please tell me How shall I approach to my requirement without embedding a string object in my exception class?
2) If I carry on with my current approach of embedding a string object and providing a method to format error message. Is my way of handling some scenarios correct ? (Issue 1 and Issue 2 in which error msg doesn't get formatted)
Issue 1 - wrong exception getting propagated to catch points ?
Issue 2 - Error Message not getting formatted in some scenarios ?
Issue 1 and Issue 2 are mentioned in comments in code below.
Kindly have a look at the code. I have given lot of comments in code so lines of code has increased but if I remove the comments it has very less lines of code.
#include <string>
#include <exception>
#include <iostream>
using namespace std;
class myexception_base : public exception {
private:
string error_msg;
public:
myexception_base(const char* str) : error_msg(str) {
// std::string here here can throw an exception while error_msg
//initialisation through MIL.
// myexception_base object will not be constructed
// and wrong exception will be propagated to catch point(Issue 1)
}
const char* what() const throw() {
try {
return error_msg.c_str();
} catch (...) {}
// c_str can throw.
// I can't remove throw specification from what()
// because what() in base std::exception has throw() specification
// In case c_str() throws an exception program will terminate
// So to stop abnormal termination of program c_str
// is wrapped in a try catch block to ignore std::string exception
// program will not terminate but what message is not reformatted
// in such scenario (Issue 2)
}
void append_error_msg(const char* str) {
error_msg.append(str);
// append can throw
// Again error_msg will not be formatted (Issue 2)
}
~myexception_base() throw() {
}
};
void f();
void f2();
void f() {
throw myexception_base("Error Msg1");
}
void f2() {
//Some intermediate Catch point will reformat e.what() msg
//by appending an error msg2
try {
f();
}
catch (myexception_base& e) {
e.append_error_msg(": Error Msg2");
throw;
}
}
int main () {
try {
f2();
}
catch(const exception& e) {
// Finally the exception is caught in the upper most layer
// and proper error_msg is given to user
cout<<e.what()<<"\n";
}
}
According to the boost documentation embedding classes which might throw during their lifetime are not an excellent candidate to be used in the exception handler mechanism, so I would like to suggest that you will simply use the good old C way of handling strings. It will require some extra effort to bring it up and running but with them you have eliminated one source of error.
So, basically there are two approaches:
In the myexception_base you declare the error_msg as being an array of N chars. In the append_error_msg you carefully check that the length of the NEW string (after the append) is not greater than N and if it is not, then you use strcat or one of the other C string handling methods. This approach might be good, since it does not allow memory leaks through the exception handling mechanism, however you can have only a limited length of error message.
In the myexception_base you declare the error_msg as being a char* (a char pointer). In the constructor you callocmemory for it (do not use new since new might throw) and in the append_error_message you realloc the pointer to be the new size (ie. old size + string to be appended.size + 1 for the 0) and then memcpy to the requested position (ie. at the position of the end of the old string in the newly allocated string). Of course, do not forget to check all the allocations/re-allocations that they have returned a valid value otherwise you might get funny behavior. And last, but not least, to avoid the classical memory leaks, free the memory of the char* in the destructor.
Good luck!
For example:
void Date::month(unsigned int inMonth) {
assert(inMonth <= 12);
_month = inMonth;
}
If this is not good practice, what is the correct way to go about this?
You shouldn't use assert to ensure that an argument to a public member function is valid. The reason is that there's no way for clients of your class to react to a failed assertion in any meaningful way (the fact that asserts are removed from release builds does not help either).
As a rule of thumb, assert should only be used for things that are strictly under your control (e.g., an argument of a private method).
In this case you're better off throwing a std::invalid_argument exception:
void Date::month(unsigned int month)
{
if(month == 0 || month > 12)
{
throw std::invalid_argument("a month must be in the [1-12] range");
}
_month = month;
}
Yes it is.
This is the right way.
Although I would call it setMonth() rather than month()
Also bare in mind that assert() is preprocessed into nothing in release builds. so if you want something that also works in release then either write your own assert or do a proper run-time check.
Another way that also gives the code more readability would be defining an enumerated type for month:
enum e_Month {
e_Month_January,
e_Month_February,
e_Month_March,
// etc..
e_Month_December
};
Now your assignment becomes:
void Date::month(e_Month inMonth) { _month = inMonth; }
Most compilers will cause an error for assigning another type to enum so you get compile time safety that it will always be in range.
That's fine, you can assert whenever it's unexpected input in your application.
In addition throw an exception something like ArgumentException in addition since you don't want to set an invalid month value.
I have some kind of an ideological question, so:
Suppose I have some templated function
template <typename Stream>
void Foo(Stream& stream, Object& object) { ... }
which does something with this object and the stream (for example, serializes that object to the stream or something like that).
Let's say I also add some plain wrappers like (and let's say the number of these wrappers equals 2 or 3):
void FooToFile(const std::string& filename, Object& object)
{
std::ifstream stream(filename.c_str());
Foo(stream, object);
}
So, my question is:
Where in this case (ideologically) should I throw the exception if my stream is bad? Should I do this in each wrapper or just move that check to my Foo, so that it's body would look like
if (!foo.good()) throw (something);
// Perform ordinary actions
I understand that this may be not the most important part of coding and these solutions are actually equal, but I just wan't to know "the proper" way to implement this.
Thank you.
In this case it's better to throw it in the lower-level Foo function so that you don't have to copy the validation and exception throwing code in all of your wrappers. In general using exceptions correctly can make your code a lot cleaner by removing a lot of data validation checking that you might otherwise do redundantly at multiple levels in the call stack.
I would prefer not to delay notifying an error. If you know after you have created the stream, that it is no good, why call a method that works on it? I know that to reduce code-redundancy you plan to move it further down. But the downside of that approach is a less-specific error message. So this depends to some extent on the source-code context. If you could get away with a generic error message at the lower-function level you can add the code there, this will surely ease maintanence of the code especially when there are new developers on the team. If you need a specific error message better handle it at the point of failure itself.
To avoid code redundancy call a common function that makes this exception/error for you. Do not copy/paste the code in every wrapper.
The sooner you catch the exceptiont the better. The more specific the exception is - the better. Don't be scared of including most of your code into a try catch blocks, apart fromt he declaration.
For example:
int count = 0;
bool isTrue = false;
MyCustomerObject someObject = null;
try
{
// Initialise count, isTrue, someObject. Process.
}
catch(SpecificException e)
{
// Handle and throw up the stack. You don't want to lose the exception.
}
I like to use helper functions for this:
struct StreamException : std::runtime_error
{
StreamException(const std::string& s) : std::runtime_error(s) { }
virtual ~StreamException() throw() { }
};
void EnsureStreamIsGood(const std::ios& s)
{
if (!s.good()) { throw StreamException(); }
}
void EnsureStreamNotFail(const std::ios& s)
{
if (s.fail()) { throw StreamException(); }
}
I test them immediately before and after performing stream operations if I don't expect a failure.
Traditionally in C++, stream operations don't throw exceptions. This is partly for historic reasons, and partly because streaming failures are expected errors. The way C++ standard stream classes deal with this is to set a flag on a stream to indicate an error has occurred, which user code can check. Not using exceptions makes resumption (which is often required for streaming ops) easier than if exceptions were thrown.