PowerMocking новый экземпляр

В классе, который я тестирую с помощью PowerMock, у меня есть следующий экземпляр класса

EmailMessage msg = new EmailMessage(getExchangeSession());

EmailMessage — это сторонний инструмент, над которым я издеваюсь, а getExchangeSession() — унаследованный защищенный метод. Мне нужно издеваться над EmailMessage, но меня действительно не волнует вызов getExchangeSession().

На данный момент у меня есть следующее, но метод getExchangeSession() все еще вызывается:

@RunWith(PowerMockRunner.class)
@PrepareForTest({EmailProvider.class, ExchangeService.class})
public class MyTest {

    @Test
    public void test() {
        EmailMessage emailMessage = createMock(EmailMessage.class);
        ExchangeService exchangeService = createMock(ExchangeService.class);
        expectNew(EmailMessage.class, exchangeService).andReturn(emailMessage);

        // test setup and call to the class under test
        Email email = new Email();
        new EmailProvider().send(email);
    }
}

public class EmailProvider() extends ClassWithProtectedAccess {
    public void send(Email email) {
        EmailMessage msg = new EmailMessage(getExchangeSession());

        // and here follows the code that I am actually testing
        // and which works on the msg (EmailMessage)
        // ...
    }
}

Первая строка EmailProvider.send() — это то, что запускает getExchangeSession() и затем дает сбой.

Так что, по-видимому, я не могу пропустить вызов getExchangeSession(), и мне, вероятно, следует также издеваться над этим методом. Это правильно? И если это так, используя PowerMock с EasyMock, как я могу издеваться над этим защищенным методом?


person homaxto    schedule 12.06.2013    source источник
comment
Вы добавили их в свои тесты? @RunWith(PowerMockRunner.класс) @PrepareForTest(Test.класс). Также вы можете проверить эту ссылку для использования powermock.expectprivate, которая также может работать для защищенных методов (я сам использую justmock, поэтому не уверен на 100%) EDIT (добавить ссылку): stackoverflow.com/questions/17027582/   -  person Josh    schedule 12.06.2013


Ответы (2)


Если в тестируемом вами классе есть эта строка:

EmailMessage msg = new EmailMessage(getExchangeSession());

тогда вы не можете пропустить вызов getExchangeSession() с помощью мощного мока конструктора EmailMessage - он вызывается до вызова конструктора, а возвращаемое значение затем передается в EmailMessage (независимо от того, реально это или высмеивается).

Итак, если вы не можете настроить свой класс так, чтобы вызов getExchangeSession работал, вам нужно будет имитировать этот вызов, как описано в этом вопросе: насмешка над защищенным методом.

person Matthew Gilliard    schedule 14.06.2013

Как я правильно понял ваш вопрос, вы ожидаете имитировать класс EmailMessage, но вам нужно пропустить вызов конструктора при создании экземпляра.

    ... test setup and call to the class under test ...
    Email email = new Email();
    new EmailProvider().send(email);

Проблема в том, как вы тестируете. Ваше намерение состоит в том, чтобы протестировать код в методе отправки. вы не можете просто вызвать этот метод send() для проверки. Вам нужно написать код для проверки операторов в методе send(), издеваясь над классами зависимостей и тестируя другие операторы в классе.

public void testSend() throws Exception 
{
  // you need to suppress the constructor before you mock the class.
   PowerMockito.suppress(PowerMockito.constructor(EmailMessage.class));
   EmailMessage emailMessage = PowerMockito.mock(EmailMessage.class);
   Email email = new Email();
   emailMessage.setSubject(email.getSubject());
  // ...your other code here ...

}
person Libin    schedule 13.06.2013
comment
Спасибо за ваш ответ. К сожалению, это ничего не изменило - getExchangeSession() по-прежнему вызывается. - person homaxto; 13.06.2013
comment
Я отредактировал ответ. Пожалуйста, дайте мне знать ваши комментарии или ваше мнение, если вы думаете иначе - person Libin; 14.06.2013
comment
Я не хочу вызывать EmailMessage.setSubjet() в своем коде, поскольку мне нужно протестировать метод EmailProvider.send(), который во время обработки вызывает EmailMessage.setSubjet(). - person homaxto; 14.06.2013