-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CHECK_THROWS() with exceptions on construction? #536
Comments
@rcdailey That's not really possible in C++, regardless of the testing framework. If a constructor throws an exception then the object basically doesn't exist. Even if you could put Useful article by Herb Sutter which explains this better than I could: http://herbsutter.com/2008/07/25/constructor-exceptions-in-c-c-and-java |
I understand how exceptions work, what I'm specifically wanting to check is whether or not something throws, but if it doesn't, it should continue to execute the other The test framework should allow me to verify NO exceptions are thrown and continue to execute assertions based on the defined variable. But there is no mechanism right now for that. We'd basically need something like this:
Right now I'm having to work around this by constructing two objects:
|
@rcdailey What about: std::unique_ptr<MyClass> mc;
CHECK_NOTHROW(mc.reset(new MyClass{"foo"}));
CHECK(mc->Stuff() == "Stuff"); |
@kirbyfan64 Nice, but might throw |
@nabijaczleweli Ok then...how about something like: char storage[sizeof(MyClass)] alignas(MyClass);
MyClass* mc = &storage;
CHECK_NOTHROW(new (mc) MyClass);
CHECK(mc->Stuff() == "Stuff"); Really, though, I doubt you'd need to worry about throwing |
That's horrible and unintuitive. Not a valid solution as far as I'm On Mon, Nov 9, 2015, 5:48 PM Ryan Gonzalez [email protected] wrote:
|
@rcdailey Not even the first one? That's the best it's going to get. This is a C++ thing, not Catch. There are benefits to manual memory control. This is not one of them! ;) |
A macro based try catch is better for this as I suggested in my earlier example |
@rcdailey Issue there is that standard C++ gives NO way of trapping an exception without opening a new scope. |
First off - do you want to check for throwing or not-throwing (you started with the former then went on to talk about the latter)? This is important as the reasoning is different in each case. If you want to check that the constructor throws, as your first example showed, then why do you need to do anything else with the object once constructed? The test would have already failed by the point. I see you are using If you want to check that the constructor doesn't throw then you have a few options. The simplest is to not use an assertion at all! Catch will still catch the exception thrown, translate it for reporting purposes, and mark the test as failed. The only downside is that you don't get the exact file/ line reported or the failing expression captured. But it's not bad for no effort and is usually the trade-off I make. The second option has already been proposed: just use heap allocation. If you're worried about bad_alloc, as @nabijaczleweli suggested, I believe you are over-thinking it. If you might get a bad alloc there then you might get it anywhere else. There is a third option, which is to move the code that uses the object off into another function. Either construct the object in the function too, or construct it at the call site and pass it in by const-ref. E.g.:
The shortcoming of this, as written, is that if something in the function throws it would also be caught by the top level assertion (either as a false positive or a false negative). This could be addressed by using |
Again my first example was wrong, I apologize. My intention was to check that it doesn't throw. Basically I wanted to handle the case where if it throws, it stops. Otherwise, execution and further tests continue. However (probably because it was Monday?), I had confused myself about this whole thing. I had forgotten that execution won't stop if it throws, so thank you for that. What I've done is split my code into 2 test cases:
This makes more sense and we track the 2 scenarios separately. I unfortunately don't get to use I don't want to use the heap because IMHO, especially for test driven development, the test should also represent how objects are meant to be used. This object specifically doesn't need to be on the heap. Many people write tests before writing their class interfaces, and it doesn't make sense to "hack" the test by using the heap for objects when it isn't necessary. I feel the solution I'm using now makes more sense from a test-case perspective, so I'll go ahead with that. |
@kirbyfan64 Nice one (the aligned storage method) |
All that talk of heap allocations and now I'm going to Garbage Collect this issue ;-) |
Suppose this:
I can't use
mc
because it's out of scope. I need a way to check construction of an object for throws. How do I do this with this test framework?The text was updated successfully, but these errors were encountered: