简体   繁体   English

Java-如何测试捕获块?

[英]Java - How to Test Catch Block?

Bit of a repost, but a certain catch-22 about not having enough reputation means I can't comment on any of the duplicate threads! 转贴一点,但是关于没有足够声誉的某些22捕捉意味着我无法对任何重复的线程发表评论! (cough cough) (咳嗽)

I'm trying to test the catch block of a try-catch using Mockito; 我正在尝试使用Mockito测试try-catch的catch块; is it possible to make a mock throw an exception that is handled by the method being tested? 是否有可能使模拟抛出由被测试方法处理的异常? I can't use doThrow()...when()... or @Test(expected = Foo.class) because the exception is handled. 我不能使用doThrow()... when()...或@Test(expected = Foo.class),因为已处理异常。 I want to test that the method handles Exceptions properly. 我想测试该方法是否正确处理了异常。

@Controller
public class StockExchangeController {

    public ModelAndView placeOrder(ModelAndView mav, MyObj myObj) {

        try {
            validator.validate(myObj); // Throws CustomException if validation fails
            mav.setViewName("successPage");

        } catch (CustomException ex) {
            mav.setViewName("failPage");
        }

        return mav;
    }
}

I'd like to be able to stub the behaviour of my "validatorObject", like 我希望能够对“ validatorObject”的行为进行存根,例如

doThrow(new CustomException()).when(validatorMock).validate();

Is there a way to do this? 有没有办法做到这一点?

The answer here (Test catch block logic with Junit and mockito) doesn't work (I believe) because the exception is handled before it gets to test level. 这里的答案(使用Junit和Mockito的Test catch块逻辑)不起作用(我相信),因为异常是在到达测试级别之前进行处理的。

Tips and thoughts much appreciated! 提示和想法深表感谢!

BDD Style Solution BDD风格解决方案

Mockito alone is not the best solution for handling exceptions, use Mockito with Catch-Exception 单独的Mockito并不是处理异常的最佳解决方案, 请将MockitoCatch-Exception一起使用

Mockito + Catch-Exception + AssertJ Mockito + 捕获异常 + AssertJ
given(otherServiceMock.bar()).willThrow(new MyException());

when(myService).foo();

then(caughtException()).isInstanceOf(MyException.class);
Sample code 样例代码 Dependencies 依赖
  • eu.codearte.catch-exception:catch-exception:1.3.3 eu.codearte.catch的异常:捕获的异常:1.3.3
  • org.assertj:assertj-core:1.7.0 org.assertj:assertj核心:1.7.0
Disadvantage 坏处
  • Only Mockito up to 1.10.8 is supported 仅支持高达1.10.8的Mockito

Why should doThrow(..).when(..)... not work? 为什么在doThrow(..).when(..)...不起作用?

The placeOrder method catches the exception and returns a testable result: placeOrder方法捕获异常并返回可测试的结果:

@RunWith(MockitoJUnitRunner.class)
public class TestStockExchangeController {

    @Mock
    Validator validator;

    @Mock MyObj myObj;

    @Test
    public void testException() throws CustomException {
        StockExchangeController sec = new StockExchangeController(validator);
        doThrow(new CustomException()).when(validator).validate(myObj);

        ModelAndView modelAndView = sec.placeOrder(new ModelAndView(), myObj);
        assertEquals("failPage", modelAndView.getViewName());
    }
}

I've tested with these two files: 我已经测试了以下两个文件:

Main source code: 主要源代码:

//src/main/java/StockExchangeController.java
public class StockExchangeController {

    private ValidationFactory factory;

    public ModelAndView placeOrder(ModelAndView mav, MyObj myObj) {
        Validator validator = factory.getValidator("S");
        try {
            validator.validate(myObj); // Throws CustomException if validation fails
            mav.setViewName("successPage");
        } catch (CustomException ex) {
            mav.setViewName("failPage");
        }
        return mav;
    }
}

class CustomException extends Exception {}

interface ValidationFactory {
    Validator getValidator(String s);
}

class Validator {
    public void validate(MyObj myObj) throws CustomException {}
}

class ModelAndView {
    private String viewName;

    public void setViewName(String viewName) {
        this.viewName = viewName;
    }

    public String getViewName() {
        return viewName;
    }
}

class MyObj {}

Test source code: 测试源代码:

//src/test/java/TestStockExchangeController.java
//various imports
@RunWith(MockitoJUnitRunner.class)
public class TestStockExchangeController {

    @Mock
    private Validator validator;

    @Mock
    private ValidationFactory validationFactory;

    @InjectMocks
    StockExchangeController target = new StockExchangeController();

    @Test
    public void testException() throws CustomException {
        MyObj myObj = new MyObj();
        when(validationFactory.getValidator(anyString())).thenReturn(validator);
        doThrow(new CustomException()).when(validator).validate(myObj);

        ModelAndView modelAndView = target.placeOrder(new ModelAndView(), myObj);

        assertEquals("failPage", modelAndView.getViewName());
        verify(validator).validate(myObj);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM