32
@Test(expectedExceptions=DataAccessException.class)
public void testUpdateSubModuleOrderDateExceptionCheck() {
    //some code to initialize//
    UserSubModuleDao userSubModuleDao = mock(UserSubModuleDao.class);
    userModuleServiceImpl.setUserSubModuleDao(userSubModuleDao);
    UserSubModule userSubModule=new UserSubModule();
    UserSubModuleId userSubModuleId=new UserSubModuleId();
      when(userSubModuleDao.findById(any(UserSubModuleId.class),eq(false))).thenThrow(DataAccessException.class);

    userModuleServiceImpl.updateSubModuleOrder(data, moduleSysId, userId);

I want to throw the Db exception for code coverage . its working if i give expected exception as : Exception.class but not for DataAccessException.class

My method in original class is as following:

public void updateSubModuleOrder(Long[] data, Long moduleSysId, Long userId) {
    try {

        for (int i = 0; i < data.length; i++) {
            SubModule subModule=new SubModule();
            subModule.setSubModuleId(data[i]);
            UserSubModuleId userSubModuleId = new UserSubModuleId();
            userSubModuleId.setSubModuleId(subModule);
            userSubModuleId.setUserId(userId);
            userSubModuleId.setUserModuleId(moduleSysId);
            UserSubModule userSubmodule = new UserSubModule();
            userSubmodule = userSubModuleDao.findById(userSubModuleId,
                    false);
catch (DataAccessException ewmsDataExp) {
        LOGGER.error(
                "Database Exception while updateSubModuleOrder because of {}",
                ewmsDataExp.getMessage());
        throw new EWMSServiceException(
                "Database Exception while updateSubModuleOrder"
                        + ewmsDataExp.getMessage());
    } catch (Exception exp) {
        LOGGER.error(
                "System Exception while updateSubModuleOrder because of {}",
                exp.getMessage());
        throw new EWMSServiceException(
                "Database Exception while updateSubModuleOrder"
                        + exp.getMessage());
    }*

i get the error

FAILED: testUpdateSubModuleOrderDateExceptionCheck
org.testng.TestException: 
**Expected exception org.springframework.dao.DataAccessException but got    org.testng.TestException:** 
**Expected exception org.springframework.dao.DataAccessException but got         java.lang.InstantiationError: org.springframework.dao.DataAccessException**
    at org.testng.internal.Invoker.handleInvocationResults(Invoker.java:1497)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1245)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)

and some error lines....

Default test

Tests run: 1, Failures: 1, Skips: 0

===============================================

===============================================

kenshinji
  • 2,021
  • 4
  • 25
  • 39
user2375298
  • 1,001
  • 4
  • 15
  • 28
  • 1
    Why are you expecting a `DataAccessException` when your class explicitly catches `DataAccessException` and converts it to something else? – Dawood ibn Kareem Mar 04 '14 at 18:28

3 Answers3

61

Change this:

thenThrow(DataAccessException.class)

to

thenThrow(new DataAccessException("..."){ })

Example:

when(userSubModuleDao.findById(any(UserSubModuleId.class),eq(false))).thenThrow(new DataAccessException("..."){});

You can only pass a Class reference when that Exception type has a No-Arg constructor, and the Spring exception does not have one.

Jen S.
  • 4,106
  • 4
  • 35
  • 44
  • it says DataAccessException cannot be instantiatied – user2375298 Mar 04 '14 at 13:12
  • Yes, it says the class cannot be instantiated because it tries to use a no-arg constructor to make it. And the class has no such constructor. – Jen S. Mar 05 '14 at 12:04
  • 4
    `DataAccessException` is an abstract class, so you can't instantiate it. You can use `new DataRetrievalFailureException("reason")` instead – wanovak May 02 '16 at 14:48
  • it is still giving errors..."java.lang.AssertionError: Expected exception: org.springframework.dao.DataAccessException"...even I have used 'new DataAccessException("..."){}' – Udit Kumawat Jun 15 '18 at 10:59
  • Worked for me, +1, but what is that { } doing? – b15 Apr 19 '19 at 14:13
29

Try

Mockito.doThrow(new Exception()).when(mockedObject).methodName(...);
Chang
  • 1,163
  • 9
  • 14
Shyam_coder
  • 869
  • 10
  • 5
  • 7
    This is a more correct answer because when...thenThrow doesn't work with the methods that return void. – Saurabh Patil Apr 17 '18 at 18:54
  • @SaurabhPatil - How will you solve the issue where void method throws exception? – PAA Jul 18 '19 at 09:04
  • @PAA Do you mean to say you want void method to throw an exception during testing? Yes that's exactly the reason why this answer is better than the other one. – Saurabh Patil Jul 23 '19 at 10:08
8

As stated by Jen S:

You can only pass a Class reference when that Exception type has a No-Arg constructor, and the Spring exception does not have one.

My solution was using Mockito:

Mockito.when(mockedObject.method(Mockito.anyString())).thenThrow(Mockito.mock(DataAccessException.class));
Seamus
  • 181
  • 1
  • 8