How to test for mandatory exceptions in TestNG?


TestNG provides an option of tracing the exception handling of code. User can test whether a code throws a desired exception or not. Here the expectedExceptions parameter is used along with the @Test annotation. This annotation is very useful in negative/exception testing.

As per TestNG documentation:

“The list of exceptions that a test method is expected to throw. If no exception or a different than one on this list is thrown, this test will be marked a failure.”

In this article, we will see how to implement expectedExceptions in TestNG.

Approach/Algorithm to solve this problem

  • Step 1: Create MessageUtil.java in src, which is need to be tested and Add an error condition inside the printMessage() method as shown in Program Code.

    Step 2: Create a class ExpectedExceptionTest.java in src, it is a test case class and Add an expected exception ArithmeticException to the testPrintMessage() test case. Please follow the program code as written in next section.

  • Step 3: Now, create and run the testNG.xml or directly testNG class in IDE or compile and run it using command line.

  • In the output, user can see tests are passed specially testPrintMessage(). This test calls the messageUtil.printMessage(); And prineMessage() function throws Airthmatic exception since it has step to divide 1/0;

  • If user removes/commented out the code int b=1/a; Output won’t be passed and it will get failed as shown in Output 2.

Example

The following code for common TestNG class − MessageUtil:

src/ MessageUtil.java

public class MessageUtil {

    private String message;

    //Constructor
    //@param message to be printed
    public MessageUtil(String message) {
        this.message = message;
    }

    // prints the message
    public void printMessage() {
        System.out.println(message);
        int a =0;
        int b = 1/a;
    }

    // add "Hi!" to the message
    public String salutationMessage() {
        message = "Hello " + message;
        System.out.println(message);
        return message;
    }
} 

The following code for common TestNG class − ExpectedExceptionTest:

src/ ExpectedExceptionTest.java

import org.testng.Assert;
import org.testng.annotations.Test;

public class ExpectedExceptionTest {
   String message = "ExpectedException";
    MessageUtil messageUtil = new MessageUtil(message);

    @Test(expectedExceptions = ArithmeticException.class)
    public void testPrintMessage() {
        System.out.println("Inside testPrintMessage()");
        messageUtil.printMessage();
    }

    @Test
    public void testSalutationMessage() {
        System.out.println("Inside testSalutationMessage()");
        message = "Hello " + "ExpectedException";
        Assert.assertEquals(message,messageUtil.salutationMessage());
    }
} 

testng.xml

This is a configuration file that is used to organize and run the TestNG test cases.

It is very handy when limited tests are needed to execute rather than full suite.

<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name = "Suite1" >
    <test name = "test1">
        <classes>
            <class name = "ExpectedExceptionTest"/>
        </classes>
    </test>
</suite>

Output

Inside testPrintMessage()
ExpectedException
Inside testSalutationMessage()
Hello ExpectedException

===============================================
Suite1
Total tests run: 2, Passes: 2, Failures: 0, Skips: 0
=============================================== 

If user removes/commented out the code int b=1/a from messageUtil.printMessage() function; Output won’t be passed and it will get failed as shown in Output 2. The reason is @Test − testPrintMessage() expecting Arithmetic Exception to be thrown but it doesn’t throw any exception.

Output

Inside testPrintMessage()
ExpectedException

org.testng.TestException: 
Method ExpectedException.testPrintMessage()[pri:0, instance: ExpectedException@327471b5] should have thrown an exception of type class java.lang.ArithmeticException

	at org.testng.internal.ExpectedExceptionsHolder.noException(ExpectedExceptionsHolder.java:82)
	at org.testng.internal.TestInvoker.considerExceptions(TestInvoker.java:749)
	at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:634)
	at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
	at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
	at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
	at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.testng.TestRunner.privateRun(TestRunner.java:794)
	at org.testng.TestRunner.run(TestRunner.java:596)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
	at org.testng.SuiteRunner.run(SuiteRunner.java:276)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
	at org.testng.TestNG.runSuites(TestNG.java:1063)
	at org.testng.TestNG.run(TestNG.java:1031)
	at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
	at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)

Inside testSalutationMessage()
Hello ExpectedException

===============================================
Suite1
Total tests run: 2, Passes: 1, Failures: 1, Skips: 0
===============================================

Updated on: 17-Aug-2023

69 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements