【问题标题】:Mock/Stub a RuntimeException in unit test在单元测试中模拟/存根 RuntimeException
【发布时间】:2015-12-31 09:40:32
【问题描述】:

在School 类中,我有一个start() 函数,它调用另一个函数doTask():

pubic class School {
    public void start() {
       try {
         doTask();
       } catch(RuntimeException e) {
          handleException();
       }
    }
    private void doTask() {
      //Code which might throw RuntimeException
    }
}

我想用RuntimeException 对start() 进行单元测试:

@Test
public void testStartWithException() {
  // How can I mock/stub mySchool.start() to throw RuntimeException?
  mySchool.start();
}

我的实现代码不容易抛出RuntimeException,如何让测试代码模拟一个RuntimeException并抛出它?

(除了纯JUnit,我正在考虑使用Mockito,但不知道如何抛出RuntimeException)

【问题讨论】:

  • 为什么doTask()会抛出异常?如果是因为输入错误,只需在测试中使用错误输入即可。如果是因为与出现意外问题的服务交互,则需要模拟或存根该服务,使其抛出异常来模拟问题。

标签: java unit-testing junit mockito


【解决方案1】:
@Test
public void testStartWithException() {
  // How can I mock/stub mySchool.start() to throw RuntimeException?
  when(mySchool.start()).thenThrow(new RuntimeException("runtime exception"));
}

您可以使用when 和thenThrow 来抛出异常。

【讨论】:

  • 我不认为 start() 是应该抛出异常的方法。
  • 我同意上述评论。我认为用户在执行 doTask() 方法时期待异常。
【解决方案2】:

您可以使用 PowerMockito 模拟私有方法以抛出 RuntimeException。像这样的:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.powermock.api.mockito.PowerMockito.doThrow;
import static org.powermock.api.mockito.PowerMockito.spy;

@RunWith(PowerMockRunner.class)
@PrepareForTest(School.class)
public class SchoolTest {

    @Test
    public void testStartWithException() throws Exception {
        School school = spy(new School());

        doThrow(new RuntimeException()).when(school, "doTask");    

        school.start();
    }
}

【讨论】:

  • 这看起来更像是 Leem.fin 正在寻找的答案,但是当您必须使用 Powermockito 代替 Mockito 时,这可能表明设计可以改进。
猜你喜欢
  • 2020-09-22
  • 2011-09-15
  • 2014-03-29
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 2017-02-09
  • 2018-11-27
相关资源
最近更新 更多