使用mockito进行Java测试:模拟类对象

时间:2017-10-18 10:40:03

标签: java unit-testing mockito

我想模仿我班上的一个对象。

public class Controller{

   private StandardEmailSender sender = new StandardEmailSender();

    public void process() throws EmailException {
       // do some stuff
       sender.sendEmail(to, subject, body);
       // do some stuff
    }
 }

我想模仿sender.sendEmail(to, subject, body);。我花了很多时间找到解决方案但是我被卡住了。我试图像这样直接模拟对象StandardEmailSender:

@Mock
StandardEmailSender sender;

@Before
public void setUp() throws EmailException {
    MockitoAnnotations.initMocks(this);

    doNothing().when(sender).sendEmail(anyString(), anyString(), anyString());
}

@Test
public void test() throws EmailException {
    Controller controller= new Controller ();
    controller.process();

    //make some asserts
}

有人能解决我的问题吗?谢谢!

2 个答案:

答案 0 :(得分:2)

你有两个选择:

  • 使您的测试用例可以手动"注入一个(模拟的)Sender对象(例如通过提供一个构造函数来设置该字段)
  • 使用Mockitos @InjectMocks注释

选项1的典型方法是使用构造函数telescoping,如下所示:

公共类控制器{

 private final Sender sender;

 public Controller() { this(new StandardEmailSender()); }
 Controller(Sender sender) { this.sender = sender; }

通过这样做,客户端仍然可以创建一个Controller实例而不必担心提供发送者,并且您的单元测试可以使用该包受保护的构造函数来提供模拟的发送者实例。

答案 1 :(得分:1)

使用依赖注入的形式,例如:

public class Controller{
   private final EmailSender sender;

   Controller(EmailSender emailSender) {
       this.sender = Objects.requireNonNull(emailSender); 
   }

   public Controller() {
      this(new StandardEmailSender());
   }     
}

在你的测试中:

@Test
public void test() throws EmailException {
    Controller controller= new Controller(mockedSender);
    controller.process();
}