Mockito的thenThrow无法捕获

huangapple go评论86阅读模式
英文:

Mockito thenThrow cannot be catch

问题

我正在使用Mockito来模拟服务层方法。
这是我的测试代码。

@InjectMocks
MyServiceImpl myServiceImpl;
@Mock
MyDAO myDAO;

@Rule
public ExpectedException exceptionRule = ExpectedException.none();

@Test
public void getAllFail(){
  Mockito.when(myDAO.getAll()).thenThrow(new DataException("mock"));
  exceptionRule.expect(ServiceException.class);
  myServiceImpl.getAllData();
}

服务代码

@Service
public class MyServiceImpl extends MyService{
  private final MyDAO myDAO;
  ...
  @Override
  public List getAllData(){
    try{
      return myDAO.getAll();
    } catch (DataException exception){
      throw new ServiceException("exception");
    }
  }
}

起初我以为通过模拟DAO类抛出异常,它会被捕捉并转换为ServiceException,但结果是

java.lang.AssertionError:
Expected an instance of com.example.exception.ServiceException
    but: <com.example.exception.DataException: mock> is a com.example.exception.DataException

在这种情况下,我该如何测试我的服务异常?请指导。提前谢谢。

英文:

I am using Mockito to mock the method of service layer.
This is my test code.

@InjectMocks
MyServiceImpl myServiceImpl;
@Mock
MyDAO myDAO;

@Rule
public ExpectedException exceptionRule = ExpectedException.none();

@Test
public void getAllFail(){
  Mockito.when(myDAO.getAll().thenThrow(new DataException(&quot;mock&quot;));
  exceptionRule.expect(ServiceException.class);
  myServiceImpl.getAllData();
}

service code

@Service
public class myServiceImpl extends myService{
  private final MyDAO myDAO;
  ...
  @Override
  public List getAllData(){
    try{
      return myDAO.getAll();
    } catch (DataException exception){
      throw new ServiceException(&quot;exception&quot;);
    }
  }
}

At first I thought that by mocking DAO class to throw exception, it would be caught by catch and turn into ServiceException but the result was

java.lang.AssertionError:
Expected an instance of com.example.exception.ServiceException
    but: &lt;com.example.exception.DataException: mock&gt; is a com.example.exception.DataException

How can I test exception of my service in this case? Please guide me. Thank you in advance.

答案1

得分: 1

我认为在预期从方法调用中出现异常并且需要正确处理异常链时,您需要使用Assertions.assertThrows。以下是我完成的部分。

服务类,包括异常和方法调用:

import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

@Service
public class SampleTestService {
    private final MyDao myDao;

    public SampleTestService(MyDao myDao) {
        this.myDao = myDao;
    }

    public List<String> getData() {
        try {
            return myDao.getStringList();
        } catch (MyDao.DataException dataException) {
            throw new ServiceException("获取数据时出错");
        }
    }

    static class ServiceException extends RuntimeException {
        public ServiceException(String message) {
            super(message);
        }
    }
}

class MyDao {
    public List<String> getStringList() {
        return Collections.emptyList();
    }

    static class DataException extends RuntimeException {
        public DataException(String message) {
            super(message);
        }
    }
}

单元测试类示例:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.List;

@ExtendWith(SpringExtension.class)
class SampleTestServiceTest {

//    private final MyDao myDao = mock(MyDao.class);

    @Mock
    MyDao myDao;

    @Test
    void testDaoThrowsException() {
        Mockito.when(myDao.getStringList()).thenThrow(new MyDao.DataException("连接数据库时出错"));
        SampleTestService sampleTestService = new SampleTestService(myDao);
        Assertions.assertThrows(SampleTestService.ServiceException.class,
                () -> {
                    sampleTestService.getData();
                });
    }

    @Test
    void testDaoReturnData() {
        List<String> colors = Arrays.asList("红色", "绿色", "蓝色");
        Mockito.when(myDao.getStringList()).thenReturn(colors);
        SampleTestService sampleTestService = new SampleTestService(myDao);
        List<String> data = sampleTestService.getData();
        Assertions.assertEquals(3, data.size());
        Assertions.assertSame(data, colors);
    }
}

如果您需要进一步的翻译,请告诉我。

英文:

I think you need to use Assertions.assertThrows when you are expecting an exception from a method call and you need chain the exception properly. Here is how I have done it.

Service class with exceptions and method calls

import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

@Service
public class SampleTestService {
    private final MyDao myDao;


    public SampleTestService(MyDao myDao) {
        this.myDao = myDao;
    }

    public List&lt;String&gt; getData() {
        try {
            return myDao.getStringList();
        } catch (MyDao.DataException dataException) {
            throw new ServiceException(&quot;Error getting data&quot;);
        }
    }

    static class ServiceException extends RuntimeException {
        public ServiceException(String message) {
            super(message);
        }
    }

}

class MyDao {
    public List&lt;String&gt; getStringList() {
        return Collections.emptyList();
    }

    static class DataException extends RuntimeException {
        public DataException(String message) {
            super(message);
        }
    }
}

Unit Test class in action

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.List;

@ExtendWith(SpringExtension.class)
class SampleTestServiceTest {

//    private final MyDao myDao = mock(MyDao.class);

    @Mock
    MyDao myDao;

    @Test
    void testDaoThrowsException() {
        Mockito.when(myDao.getStringList()).thenThrow(new MyDao.DataException(&quot;Error connecting to database&quot;));
        SampleTestService sampleTestService = new SampleTestService(myDao);
        Assertions.assertThrows(SampleTestService.ServiceException.class,
                () -&gt; {
                    sampleTestService.getData();
                });
    }

    @Test
    void testDaoReturnData() {
        List&lt;String&gt; colors = Arrays.asList(&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;);
        Mockito.when(myDao.getStringList()).thenReturn(colors);
        SampleTestService sampleTestService = new SampleTestService(myDao);
        List&lt;String&gt; data = sampleTestService.getData();
        Assertions.assertEquals(3, data.size());
        Assertions.assertSame(data, colors);
    }
}

huangapple
  • 本文由 发表于 2020年10月25日 15:36:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/64521402.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定