PHPUnit Testing Exceptions for Laravel Resource Controllers - unit-testing

Is it possible to test Exceptions with Laravel resource controllers? Every time I try to do the following:
/**
* #expectedException Exception
* #expectedExceptionMessage Just testing this out
*/
public function testMyPost() {
$response = $this->call('POST', '/api/myapi/', array('testing' => 1));
}
I get:
Failed asserting that exception of type "Exception" is thrown.
I've tried this with \Exception and Exception.
In my resource controller I have:
public function store() {
throw new \Exception('Just for testing!');
}
Does anyone has any idea of I can test Exceptions? I've also tried using:
$this->setExpectedException('InvalidArgumentException');

The problem is as hannesvdvreken states; the exception is caught. An easy work-around is to tell Laravels errort/exception handler, that when we are testing, we just want our exceptions thrown.
That could look something like this:
// If we are testing, just throw the exception.
if (App::environment() == 'testing') {
throw $e;
}
For Laravel 5, this should go in the render method in app/Exceptions/Handler.php
For Laravel 4, this should go in app/start/global.php within:
App::error(function(Exception $exception, $code)...

Don't focus on the notation of #expectedException. The problem is the Exception is catched somewhere. Maybe with the default App::error(function(Exception) {... inside the app/start/global.php file.
Or maybe you did a try catch somewhere. Try making a custom Exception that does not get catched by a generic exception catcher that catches everything that's inherited from Exception.

Related

Javascript decorator that handles unhandled promise rejection

can someone share a way to build a decorator, which will wrap each method of a class with try-catch block, so all method errors are handled the same way while decreasing the amount of code boilerplate? The final implementation should look like this:
#ExceptionHandler()
export class MiserableClass {
public miserableMethod(){
throw new Error('Error in miserableMethod()')
}
}
Exception handler should contain logic like logging the error to console, logging error to Sentry, etc.

Moq - Testing that a controller method throws an exception

I have a controller method that throws a custom exception if a loop through a list of ids doesn't find a specified id, otherwise it returns a partial view.
I've done the test to see if it successfully returns a partial view but how do I test that the method fails and that the custom exception is thrown?
You can do a simple try/catch and perform Assert.Fail if you don't catch the expected exception. However, most unit testing frameworks provide an automated way of testing for exceptions.
Microsoft's MSTest has the ExpectedException attribute which can be applied to a test method:
[ExpectedException(typeof(ArgumentNullException))]
[TestMethod]
public void DoSomething()
{ ... }
If the test method above does NOT throw an ArgumentNullException, MSTest will mark the test as a fail.
NUnit has a more granular Assert.Throws that gives you more specific control of exactly where in the test method an exception is expected.

Groovy wraps a java exception in its own runtime.InvokerInvocationException

I'm using groovy to write unit tests for my java project (I'd advise all to try it out)
One of my unit tests is testing that the tested code (in java) catches an exception of a specific type and rethrows an app exception:
java code (under test):
try
{
dao.save(obj)
}
catch(DataIntegrityException dupex)
{
....
throw new AppException("duplicate name");
}
The groovy test code mocks(proxies) the dao call using groovy's map of closures
[ save:
{ obj->
...
throw new DataIntegrityException("duplicate"); //DataIntegrityException is a runtime exception (unchecked)
}
] as DAO;
Pretty straightforward. However, when executing the test class, the actual exception thrown is groovy's runtime.Invoker.InvocationException which wraps the DataIntegrity exception. Obviously, the java code knows nothing about groovy and its exceptions, so the catch block is not executed.
I'm using Netbeans 7 to actually execute the test and it just uses groovyc to compile the groovy file into a java class, and so it's just being executed as a normal JUnit test.
Anyone know how to overcome this? couldn't find it listed in groovy's bugs, but sure seems like one.
Just using this for a little more space, not yet an answer. I can get the following (minimal) setup to work:
Dao.java
public interface Dao { void save(Object obj) throws DataIntegrityException; }
DataIntegrityException.java
public class DataIntegrityException extends RuntimeException {
public DataIntegrityException(String str) { super(str); }
}
Test.java
public class Test {
public void doIt(Dao dao) {
try {
dao.save(new Object());
} catch (DataIntegrityException e) {
System.out.println("Caught DataIntegrityException")
}
}
}
test_case.groovy
d = [save: { throw new DataIntegrityException('duplicate') }] as Dao
new Test().doIt(d)
This works, i.e., it prints "Caught DataIntegrityException" to the console, using Java 6 and Groovy 1.8 (which is what I have on my machine. At the very least, the issue must lie somewhere outside of the code you've posted here.
Personally, I'd think you'd need some step-through debugging. It seems likely that the exception is being thrown from elsewhere in the code (perhaps in whatever is contained in the ellipses in your version prior to throw new DataIntegrityException()).

Exception handling for Unit Tests in c++

I'm trying to test a c++ code on an Nunit framework but I keep getting the following Exception
System.Runtime.InteropServices.SEHException : External Component has thrown an exception.
which is supposedly perfectly normal (I assume) anyway I wanna ignore it. (i.e. Use ExpectedException) This is my .h file
[Test, Description("Tests if an Entity has been successfully Locked")]
void test_LockOperation();
and the .cpp file
void TestDmObstacles::test_LockOperation()
{
lockVal = DbtoDmObstaclesAdapter::lock( CmnGuid::parseString( L"3B6DB8F8-4BA7-DD11-B6A7-001E8CDE165C" ) );
//When lock is successful the lockVal is 0
Assert::AreEqual(0, lockVal);
}
I wanna use ExpectedException but I don't know how to do it in c++. I tried the try/catch method as well but it didn't work (I just put the Assertion in the catch block)
PS: I can't use another framework it has to be Nunit
EDIT
Here is the try/catch approach I used
void TestDmObstacles::test_LockOperation()
{
try
{
lockVal = DbtoDmObstaclesAdapter::lock( CmnGuid::parseString( L"3B6DB8F8-4BA7-DD11-B6A7-001E8CDE165C" ) );
}
catch (...)
{
//Assert::Fail();
Assert::AreEqual(0, lockVal);
}
}
Is the exception expected, or is the exception acceptable?
If it is expected, then your unit test framework should have some kind of API that allows you to state the expected exception, and to fail the test if it does not occur. A quick trawl through the documentation yields the incantation:
[ExpectedException( "System.ArgumentException" )]
(replace System.ArgumentException with the exception you're expecting.)
If the exception is merely acceptable, then I would say that either your code or your test is broken. A unit test is to test that expected things happen. If there is a result in your test that only may yield a particular result, then you are not testing a consistent view of the unit from test to test. Hence, you're not really testing it.
It might indicate, for example, that your code is leaking an unexpected exception that it should be handling instead.
Your code sample doesn't match what you are trying to achieve : if the exception is expected, than catching it is not supposed to fail the test.
Note that I wouldn't recommend (at all) for the test to catch (...) : any thrown exception will induce the same test result, which I doubt is what you want.

Having trouble getting NUnit's Assert.Throws to work properly

I could have sworn that I've used NUnit's Assert.Throws to determine whether or not a particular exception gets thrown from a method, but my memory has failed me before. I read this post here on SO, but it didn't answer my question, as I know the correct syntax, and I don't want to do anything with the exception that gets returned (I don't want to look at the Exception's members, though this could be useful down the road).
I wrote unit tests to prove my lack of understanding in the use of Dictionary, and couldn't get it handle the KeyNotFoundException that gets thrown. Instead of NUnit catching it and passing the test, I get an unhandled KeyNotFoundException error when I run. I verified that I don't have the VS IDE set up to break on thrown .NET exceptions.
I've tried this two ways:
Assert.Throws( typeof(KeyNotFoundException), () => value = prefs["doesn't exist"]);
and
Assert.Throws<KeyNotFoundException>( () => value = prefs["doesn't exist"]);
but both result in an unhandled exception. What am I missing here?
UPDATE seems like others can't reproduce this. Here's a screenshot:
This is an old thread, but try turning off Enable Just My Code in Visual Studio under Tools->Options. With that on, the debugger is trying to be helpful and stops at the last possible point within your code before the exception gets swallowed.
Or, at least that's my understanding of it.
If you turn off Enable Just My Code, the Assert.Throws should work correctly.
The debugger is stating that your exception is not being handled by user code, which is technically true. To demonstrate, I'll use the sample test sgreeve provided
[Test]
public void demonstrateThatExceptionThrown()
{
string value;
Dictionary<string, string> test = new Dictionary<string, string>();
Assert.Throws(typeof(KeyNotFoundException), () => value = test["h"]);
}
When you execute it, you will receive a warning in VisualStudio that the exception is unhandled in user code. If you look at the callstack, you will see something like
[External Code]
CodeTests.DLL!CodeTests.MiscTests.demonstrateThatExceptionThrown.AnonymousMethod()
[External Code]
CodeTests.DLL!CodeTests.MiscTests.demonstrateThatExceptionThrown()
[External Code]
Because you have specified a delegate, the exception is happening within the "AnonymousMethod" that was created. This is being called by the .Net framework. The debugger is stopping because your delegate isn't handling the exception before it gets passed back to the framework. It doesn't care that further up the stack it might be handled in your code (perhaps since there is no way to guarantee that the external code will handle the exception correctly.)
To have VisualStudio see this as a handled exception, use the ExpectedException attribute and remove the delegate, like so:
[Test]
[ExpectedException(typeof(KeyNotFoundException))]
public void demonstrateThatExceptionThrown()
{
string value;
Dictionary<string, string> test = new Dictionary<string, string>();
value = test["h"];
}
Not a direct answer, but I personally prefer to tag my tests with
[ExpectedException(typeof(KeyNotFoundException))]
public Test ShouldDoTheStuff() {
...
}
Does this work for you? I don't actually see anything wrong with your code per se.
EVEN MORE RECENTLY UPDATED ANSWER!
After our conversation in the comments added to this answer, I suspect that the nunitit test runner is the problem here. I don't believe there's anything wrong with your test as I have no problem executing it either using NUnit GUI or the excellent Resharper test runner.
UPDATED ANSWER
After seeing your screen shot, I tried stepping through my test with the debugger and saw exactly the same prompt about the unhandled exception. If I carry on stepping past that error, the test passes when I reach the end of the assertion.
When I run the test in none-debug mode using either the NUnit GUI or the Resharper 4.5 test runner, the test passes as expected every time.
Sorry to ask the obvious question, but what are you executing your test with? i.e. which test runner?
The exact code I've executed is:
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace ClassLibrary1
{
[TestFixture]
public class DictionaryTest
{
[Test]
public void demonstrateThatExceptionThrown()
{
string value;
Dictionary<string, string> test = new Dictionary<string, string>();
Assert.Throws(typeof(KeyNotFoundException), () => value = test["h"]);
}
}
}