2017-10-18 166 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(); 
}