Codeninja
Codeninja

Reputation: 322

TestNG how to test exceptions in unit testing

I need to test the Exception but it gets the following error.

org.testng.TestException: 
Method ContactIdentifierHelperTest.test()
[pri:0, instance:se.cambio.contactadministration.contact.helper.ContactIdentifierHelperTest@6d7b4f4c]
 should have thrown an exception of type class SpiderException

Test method:

  @Test(expectedExceptions = { SpiderException.class })
  public void test()  {
    ContactData contactData = getContactData();
    contactIdentifierHelper.getSpellId(contactData);
  }

Method tested:

  public String getSpellId(final ContactData contactData)
  {
    String s = null;
    try
    {
      s = someMethod();
    }
    catch (SpiderException e)
    {
      e.printStackTrace();
    }
    return s;
  }

Where have I gone wrong in this?

Upvotes: 0

Views: 421

Answers (2)

Andrei Dragotoniu
Andrei Dragotoniu

Reputation: 6335

I suggest you change the way you think about this.

You need a repeatable, predictable way for your tested method to thrown an exception. One way to achieve that is via certain inputs.

Imagine your method looks something like this:

public String getSpellId(final ContactData contactData) throws SpiderException
{
    if ( contactData == null ) throw new ArgumentException("input is null")
    //some other code
}

this is something repeatable, you can always trigger the exception by passing null. You know how your code should behave, there is no uncertainty and you can test for this behaviour.

What you have however is another method call, which might fail, but you don't know how and why. This is a big no, when it comes to unit testing.

You might be better served by adding an exception test for your other method and not bother with this one.

What you really want to avoid is for your test to have too much knowledge of the code under test. You don't want to have to go through who knows how many layers in order to achieve what you want, because this leaves you with brittle tests which will need to change every time a code change happens.

So, change the way you think about the code and aim to make it testable. Also, if you want to test for an exception, you must make sure you don't catch that exception as this will hide the actual thing.

Upvotes: 1

Renato
Renato

Reputation: 2167

The expected behavior is that your method throws an Exception and your test fails, but it cannot never be successful (and this is correct), because you catch the exception in the body of your method.

In order to throw the exception you can simply have:

public String getSpellId(final ContactData contactData) throws SpiderException
{
    return someMethod();    
}

However, keep in mind that your test will be successful only if someMethod() effectively throws an exception!

Now, let me make a remark: this test does not have any sense: you are testing getSpellId but your buisiness logic is inside someMethod, and furthemore, getSpellId accept a parameter that is never used in the body ...

Upvotes: 1

Related Questions