2015-11-09 11 views
0

У меня есть класс, который содержит публичный статический метод getProduct(String name):MissingMethodInvocationException от Mockito когда делать модульное тестирование

public class ProductManager { 
    public static Product getProduct(String name) { 
     Product prod = findProduct(name); 
     return prod; 
    } 
} 

Другой CustomerService класс использовать выше ProductManager:

public class CustomerService { 
    ... 
    public void handleProduct() { 
    Product appleProd = ProductManager.getProduct("apple"); 
    doHandle(appleProd); 
    } 
} 

I модульный тест handleProduct() метод в CustomerService класс. Я использую mockito для имитации ProductManager.getProduct("apple") участия в тесте:

public class CustomerServiceTest { 
    @Test 
    public void testHandleProduct() { 
    Product mockProd = Mockito.mock(Product.class); 

    // MissingMethodInvocationException 
    when(ProductManager.getProduct("apple")).thenReturn(mockProd); 
    ... 
    } 
} 

Однако, когда я запускаю мой тест, я получил от MissingMethodInvocationException Mockito:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'. 
For example: 
    when(mock.getArticles()).thenReturn(articles); 

Also, this error might show up because: 
1. you stub either of: final/private/equals()/hashCode() methods. 
    Those methods *cannot* be stubbed/verified. 
    Mocking methods declared on non-public parent classes is not supported. 
2. inside when() you don't call method on mock but on some other object. 

Он жалуется, что внутри when() я не вызвать метод , но я вызываю публичный статический методProductManager.getProduct("apple") в when(...), почему Mockito возник эту ошибку для меня? Я не понимаю.

ответ

1

Mockito не может издеваться над статическими методами. Сделайте это методом экземпляра, и ваш код будет работать.

Существуют и другие рамки, которые позволяют это (например, Powermock), однако это довольно плохая практика и признак плохого дизайна. Вы должны создать экземпляр и выполнить инъекцию зависимостей. Если метод настолько мал, что его можно тестировать косвенно при тестировании другого класса (например, Math.max()), то нет необходимости насмехаться.

В коде, который вы опубликовали, есть getProduct(), но в трассировке стека getArticles() - Я предполагаю, что код был просто упрощенным примером, в то время как трассировка стека актуальна.

Вот несколько статей, объясняющих проблему тестирования/насмехаясь статические методы:

+0

Это глупо. Статический метод полностью не поддается тестированию с помощью mockito? Есть ли способ обхода статического метода в mockito? Да, getArticles() - это примеры из mockito, когда он вызывает исключение. – user842225

+0

Вы не можете сделать это с Mockito, и вы все равно не должны этого делать. См. Мой отредактированный ответ. –

+0

Я вижу ваш отредактированный ответ, вы сказали, что это плохой дизайн, чтобы иметь статическую функцию, но вы не дали повод, почему это плохой дизайн? Что плохого в публичном статическом методе в моем случае? Если бы вы могли объяснить, это было бы здорово. – user842225

Смежные вопросы