PHPUnit test code inside catch block - unit-testing

I have a Symfony controller using try...catch.
I use phpunit to test my application. I have searched but havent found a way how to test the code inside a catch exception. How can I force php unit to pretend that something went wrong and enters the catch block and test this as well?
ie:
try {
$foo = 1;
} catch (\Exception $ex) {
$mail = new Mail();
$mail->sendMail();
return new Response();
}
How can I tell phpunit to throw an \Exception so it will test code inside catch block of above?

Well, under those conditions, it will obviously not throw any exceptions, but consider the function your try/catch lies within. You need to unit test that function, and provide arguments that will cause it to fail, and catch.
For instance:
public function doStuff($argument) {
try {
$parsed = (int)$argument; //but what if $argument is a string with letters
} catch (\Exception $ex) {
//do stuff
}
To test that an exception is thrown when you mess it up:
public function testDoStuff() {
// get a mock of the class, let's just call it $mock
// do some regular asserts if you want
$this->setExpectedException('\Exception');
$mock->doStuff("haha, you can't parse this");
}

If you really have some complex stuff in your catch block you can move it to separate protected method of the controller and test it separately. You can easily access protected method outside of its class using reflection.

Related

unit test for catch block using kotlin mockito

try {
return Response.ok(payHandler.getFeesForPay(body, config)).build()
}
catch (e: Exception) {
return exceptionHelper.buildResponseFromException(e)
}
How to write unit test using mockito for code in catch block
Without a more detailed code, all we can suggest you is to mock payHandler to throw an exception as follows:
when(payHandler.getFeesForPay(any(), any()))
.thenThrow(NullPointerException.class);

Showing Not Covered by Test if method throw exception junit mockito

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.

How to make a catch block with more arguments that i catch it from objects from classes for exceptions?

I have three exceptions classes in my code, so when i want to use more arguments (more different objects to catch i get an compile error) so how i can catch more exceptions?
i tried to do this
try{
User * u = new FacebookUser(username,password,email,friends,likes,comments);
network += u;
}
catch(InvalidPassword ip,InvalidEmail ie,MaximumSizeLimit ms){
ip.message();
ie.message();
ms.message():
}
First exception is for checking if password have at least 1 uppercase,lowercase and number.
Second exception is for checking if email have at least 1 # .
Third exception is for changing static variable, if the maximum is equal to n throw exception.
My throw exceptions for email and password are in my user constructor.
If you have multiple types of exceptions you want to catch, you need to catch them separately - otherwise, what would be in say ip if InvalidEmail was thrown?
Correct code will be like
try {
//...
} catch (const InvalidPassword& ip) {
//...
} catch (const InvalidEmail& ie) {
//...
} catch (const MaximumSizeLimit& ms) {
//...
}
Othewrise, you can make all this exceptions inherited to the same base class and make message virtual function of this base class.
(as a separate note, it is sometimes considered bad style to use exceptions for such checks)

Catching exception in Googletest Setup()

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.

NSubstitute conditions for throwing exception other than parameters

I'm using NSubstitute to mock a class that my method under test uses. This mocked class may throw a particular exception under certain conditions.
The method that I'm testing has some "retry" logic that it executes when it catches this exception. I'm trying to test this retry logic. So, I need a particular method of this mocked class to throw the exception sometimes, but not other times. Unfortunately, the method that throws this exception has no parameters, so I can't base the throw logic on parameters.
How can I make the mocked object's method throw the exception either:
A) ...the first N times it's called
or
B) ...based on the parameters some other method that's called before it
or
C) ...under any other condition other than the parameters passed in
To give you a clearer picture of what I'm trying to do, my code is something like:
IDataSender myDataSender = GetDataSender();
int ID = GetNextAvailableID();
myDataSender.ClearData();
myDataSender.Add(ID,"DataToSend");
bool sendSuccess = false;
while (!sendSuccess)
{
try
{
myDataSender.SendData();
sendSuccess = true;
}
catch (IDCollisionException)
{
ID++;
MyDataSender.ClearData();
myDataSender.Add(ID,"DataToSend");
}
}
So, I need to test my retry logic, and I need to simulate that IDCollisionException. However, I can't have the SendData() throwing the exception every single time, or the retry loop will never succeed.
What can I do here?
If I understand the question correctly, you can use When..Do and close over a local variable to get this behaviour.
const int throwUntil = 3;
var callsToSendData = 0;
var dataSender = Substitute.For<IDataSender>();
dataSender
.When(x => x.SendData())
.Do(x =>
{
callsToSendData++;
if (callsToSendData < throwUntil)
{
throw new DbCollisionException();
}
});
Similarly, you can also use callbacks to locally capture parameters passed to other methods, and access them within the Do block (rather than just using a counter).