Пересмешка на основе звонков - PullRequest
11 голосов
/ 26 января 2012

Я пытаюсь высмеять некоторые методы, основанные на отражении.Ниже вы можете увидеть детали,

Тестируемый класс

public class TracerLog {
    @AroundInvoke
    public Object logCall(InvocationContext context) throws Exception {
        Logger logger = new Logger();
        String message = "INFO: Invoking method - " 
                + context.getMethod().getName() + "() of Class - " 
                + context.getMethod().getDeclaringClass();

        logger.write(message);
        return context.proceed();
    }
}

Тест

public class TracerLogTest {

@Mock
InvocationContext mockContext;
@Mock
Logger mockLogger;
@InjectMocks
private TracerLog cut = new TracerLog();

@BeforeMethod
public void setup() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void logCallTest() throws Exception {
    when(mockContext.proceed()).thenReturn(true);
    when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass");
    cut.logCall(mockContext);
    verify(mockContext).proceed();
}

}

или

@Test
public void logCallTest() throws Exception {
    when(mockContext.proceed()).thenReturn(true);
    when(mockContext.getMethod().getName()).thenReturn("someMethod");
    when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass");
    cut.logCall(mockContext);
    verify(mockLogger).write(anyString());
    verify(mockContext).proceed();
}

Но тесты завершаются с ошибкой NullPointerException.Я понимаю, что я делаю что-то не так с насмешливыми понятиями, но я не понимаю, что это такое.Не могли бы вы пролить свет на это, а также предложить мне, как этот метод может быть проверен?

Спасибо.

Ответы [ 2 ]

21 голосов
/ 26 января 2012

Вам нужен объект Method и объект Class.Согласно вашему комментарию, Mockito не может издеваться над методом, поэтому вам нужен настоящий.Я не проверял это, но я верю, что это сработает.Вместо:

when(mockContext.getMethod().getName()).thenReturn("someMethod");
when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass");

Вам нужно:

// any method will do, but here is an example of how to get one.
Method testMethod = this.getClass().getMethod("logCallTest");

when(mockContext.getMethod()).thenReturn(testMethod);

Очевидно, getName() больше не будет возвращать "someMethod", а getDeclaringClass().getName() вернет имя этого тестового классапример), но хотя вы не можете выбрать, что они возвращают, то, что они возвращают, все еще детерминировано, поэтому вы должны иметь возможность проверить все, что вам нужно.(Конечно, если вам нужно было шпионить или убедиться, что был сделан вызов для самого объекта Method, вы все равно застряли.)

3 голосов
/ 26 января 2012

Да, проблема в том, что mockContext.getMethod() вернет ноль.Поэтому каждый раз, когда вы запускаете это, затем вызываете что-то в результате (getDeclaringClass () или getName ()), вы получите NPE.Возможно, вы захотите использовать ответ RETURNS_DEEP_STUBS по умолчанию при настройке макета.Что-то вроде

@Mock( answer = RETURNS_DEEP_STUBS ) private InvocationContext mockContext; 

должно сработать.

...