2017-10-18 131 views
1

我想嘲笑我的课内的对象。Java测试与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

你有两个选择:

  • 有可能使你的测试用例(通过提供一个构造函数来设置该领域为例)为“手动”注入(嘲笑)发件人对象
  • 化妆使用Mockitos @InjectMocks注释

的选项1的典型方法是使用伸缩式构造,像这样:

公共ç姑娘控制器{

private final Sender sender; 

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

通过这样做,客户端仍可以创建一个控制器实例,而无需担心提供发件人和单元测试可以使用包受保护的构造提供了嘲弄者实例。

+0

好,谢谢,@InjectMocks诠释完美的作品 – Kagelmacher

+0

@Kagelmacher是它。但有些人仍然不喜欢它:https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/ ...并在如果您发现我的答案充足,请不要忘记在某些时候接受。 – GhostCat

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(); 
}