I have a test class which contains SetUp() and TearDown(), with certain inputs and is run with a variety of different inputs. When certain inputs are used, an exception will be thrown within SetUp() rather than in the body. This is expected and though it is not strictly part of the test, I would prefer not to have to move my SetUp() code into the body of the test just for this specific instance. However, I can't find a way of catching the exception here. My code is similar to the following:
struct MyInputs {
int first_;
const char* second_;
const char* third_;
};
The test class is pretty standard gtest boilerplate:
class MyTestClass : public ::testing::TestWithParam<MyInputs> {
public:
virtual void SetUp();
virtual void TearDown() {};
// etc...
}
void MyTestClass::SetUp() {
// Do some stuff here using MyInputs.first_ which may throw
// a "thrown from here" exception
}
I have a standard test closure though it's irrelevant to the problem here really - it doesn't get this far.
TEST_P(MyTestClass,aSpecificTest) {
// ... some stuff ...
}
Then I create the loop with multiple inputs:
INSTANTIATE_TEST_CASE_P(MultipleTests,
MyTestClass,
::testing::Values( MyInputs( 1234, "ABC", "XXX"), // <-- No exception thrown
MyInputs( 5678, "DEF", "ZZZ") ) ); // <-- Exception thrown
When I run the code, I get the error:
C++ exception with description "thrown from here" thrown in SetUp().
when it hits the 'bad' input. Is there a way I can catch this and either ignore or set an EXPECT_ type clause? I realise that I can simply put a try/catch in the SetUp(), but was rather hoping that I could use EXPECT_THROW somewhere to incorporate into the test.
Related
implementation class have two method :
test method call by test case and inside test() i call test2() which is throw exception, now I want
to
cover this method by test case but in sonar it showing not covered by test , so how i can covered this
method:
[service implementation class][1]
public void test()throws SystemException {
LOGGER.info("Testing exception");
test2(); //not covered by test
LOGGER.info("Testing exception 2");//not covered by test
System.out.print("hi");//not covered by test
}
public void test2() throws SystemException {
LOGGER.info("Testing exception");
throw new SystemException();
}
Test case: this is test which is call service.test1() method but in code coverage it is showing not
covered by test:
#Test(expected = SystemException.class)
public void test1() throws SystemException {
service.test();
}
You're being very unclear about what exactly your problem is. When you refer to "this method" or "it", you have to be clear about exactly what that means.
Concerning your existing code, if you're wondering how to "cover" the last two lines of method "test", it's not possible to cover them. In fact, it's not at all possible to execute those lines at all. If method "test2" throws that exception, it will exit method "test2" along with method "test" without executing the rest of method "test".
To be clearer about what you're asking, you might try changing your method names to be a little more different, and refer to those method names explicitly.
I have a C++ object running in a separate thread, with its state being updated in an asynchronous manner. The code resembles the following:
class Controller : public Listener {
public:
// Controller methods, to be called by the user from the main thread
// My problem is that I am obliged to duplicate the call to validateState() in all methods
void doAction1() {
validateState(); // explicit call to validate state
}
void doAction2() {
validateState(); // explicit call to validate state duplicated here and in every doActionX() method.
}
...
private:
// Override Listener virtual methods(which are used as callbacks), called in an async manner
void onXYZ() override;
void onError(std::string) override { /* update m_error */ }
...
// validate that no error has occurred
void validateState() {
if(m_error) throw m_error;
}
private:
Error m_error; // updated
};
I thought of a solution, to overload operator-> and call validateState() once inside, and thus removing the duplicated calls. However, the problem is that the user must do controller->doAction1() and be prohibited from doing controller.doAction1().
I can also think of other semantic issues with this approach:
One would expect overloading operator-> would be done for memory management issues (such as having a custom allocator), and not just any random operation.
the lack of symmetry between -> and .
Is duplicating the call for validateState() on newly added methods OK here? The intent being to avoid over-engineered designs.
What would be a plausible approach/design here?
It's perfectly fine for all the public functions of a class to call the same private function. Your function is just making sure the implicit this parameter is valid, which is the same as any other parameter validation
void Controller::doAction1(Arg1 arg1)
{
// ensure preconditions hold
validateState();
validateArg1(arg1);
// "real" code
}
void Controller::doAction2(Arg2 arg2, Arg3 arg3)
{
// ensure preconditions hold
validateState();
validateArg2(arg2);
validateArg3(arg3);
// "real" code
}
In my code I throw my custom file_error exception, which is derived from std::runtime_error. In a different module I catch exceptions for that operation and want to handle my file_error like this:
try
{
base::create_directory(INVALID_NAME, 0700);
...
}
catch (const base::file_error &exc)
{
...
}
catch(std::runtime_error &exc)
{
...
}
catch(std::exception &exc)
{
...
}
file_error is declared as:
namespace base {
class file_error : public std::runtime_error
{
int sys_error_code;
public:
file_error(const std::string &text, int err);
error_code code();
int sys_code();
};
}
However, the catch branch for file_error is never triggered. Either I end up in the runtime_error branch or, if I remove that, in the exception branch.
However, this works fine in Linux + Win (gcc, VS) while it does not work on Mac (clang). Any idea what could be wrong here?
Update:
Here's the lldb output when I reach the runtime_error branch:
(lldb) p exc
(const base::file_error) $0 = {
std::runtime_error = {
__imp_ = (__imp_ = 0x0000000000000000)
}
sys_error_code = 13923331
}
That clearly indicates the exception is indeed of type base::file_error. It's just not catched in its associated catch block.
Update 2:
Declaring an own error based on file_error in the same file as the test code above like this:
class test_error : base::file_error {
public:
test_error(const std::string &s) : base::file_error(s, 0) {};
};
allows me to catch it in a test_error block and in a catch-all block, but not in base::file_error, std::runtime_error or std::exception blocks. Weird.
Update 3:
After a lot of experimenting I now think this is a type mismatch issue, similar to the ODR-violation but a different kind. The types in the dylib and in the test app are not considered the same and hence the exception is not catched, unless I throw that base::file_error exeption directly in the test code.
class test_error : base::file_error
allows me to catch it in a test_error block and in a catch-all block, but not in base::file_error, std::runtime_error or std::exception blocks.
Your exception classes need to derive publicly from base exception classes. Otherwise you won't be able to catch them via the base class:
class test_error : public base::file_error
The solution for this problem is to avoid using the compiler option -fvisibility=hidden (or make it default) in the test application. Read more about this here: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options. In particular this part:
Note that -fvisibility does affect C++ vague linkage entities. This
means that, for instance, an exception class that is be thrown between
DSOs must be explicitly marked with default visibility so that the
‘type_info’ nodes are unified between the DSOs.
An overview of these techniques, their benefits and how to use them is
at http://gcc.gnu.org/wiki/Visibility.
Relevant part of the code snippet. The above code snippet results in generating the following error in Win VC 8 compiler during exit. Making the assertion pass in destructor fixes the crash. This error is observed only in the windows and it works fine in linux.
class BasicMathTest: public TestFixture
{
CPPUNIT_TEST_SUITE(BasicMathTest);
CPPUNIT_TEST(testAdd);
CPPUNIT_TEST(testMultiply);
CPPUNIT_TEST(testDivide);
CPPUNIT_TEST_SUITE_END();
class A
{
public:
~A()
{
CPPUNIT_ASSERT_MESSAGE( "BasicMath::Addition", 0 );
}
};
A ob;
public:
virtual void setUp( void );
virtual void tearDown( void );
void testAdd( void );
void testMultiply( void );
void testDivide( void );
private:
BasicMath *obj;
};
int main()
{
TestRunner testrunner;
Test *tests = TestFactoryRegistry::getRegistry().makeTest();
testrunner.addTest( tests );
testrunner.run( m_testResult );
m_outputter->write();
return !m_collector.wasSuccessful();
}
The constructor and the destructor of a TestFixture are not protected against exceptions. If you want to use assertions in this stage you'd need to change the code so you can move the code that uses assertions (throws an exception) into setUp/tearDown.
Actually it might not even terminate with an unhandled exception and instead crash because you might get a second exception while unwinding the stack. To separate the state for different tests the test fixture is wrapped into a functor and each test gets a new instance that is stored in a vector. This hows once more that it is nearly always a bad idea to throw an exception in a destructor.
Hello to all and sorry for my english!
How can I do the title above?
For example, I have a class contains a some functions that can throw exceptions:
class cl {
public:
void f1();
void f2();
};
void cl::f1()
{
// throw exception
}
void cl::f2()
{
// throw exception
}
I need to handle them.
Are there any other method to handle exceptions (that throws in my class) in one place of the code except code like this:
void cl::f1()
{
try
{
// throw exception
}
catch (...)
{
// handling
}
}
void cl::f1()
{
try
{
// throw exception
}
catch (...)
{
// handling
}
}
or this:
int main()
{
cl c;
try
{
f1();
f2();
}
catch(...)
{
// handling
}
}
?
Thanks in advance!
Are there any other method to handle exceptions (that throws in my
class) in one place of the code except code like this:
In my opinion you would typically only handle an exception when:
You can remedy it i.e do something about it e.g allow the user to select a different file.
You can add additional information.
For the latter case, it would mean throwing a new exception (possible of different type) from the handler.
If neither of the above hold, let it propagate to a level where it can be handled. In your case, I would not have a try/catch within f1 and f2, but only at the callsite (in main).
You might ask whether one cannot(should not) do certain cleanup work in the catch handler. I personally have never found this to be necessary if/when one uses the stack/scope to clean up see RAII. I/we usually have one catch handler per thread at the highest level, and this simply performs logging. We catch (and use exceptions) for runtime errors mostly. For logic errors we use assert (even in release mode), but this can be (and have been) debated often.