2014-02-17 5 views
1

Давайте посмотрим на этот кусок кода:EasyMock + PowerMock: как насмехаться над полем?

public class A { 

     public void doSmth() { // pay attention - void method 
      // impl 
     } 
    } 

    public class B { 
     private A a_instance; // null 

     public void doSmthElse() { 
      a_instance.doSmth(); // NPE here without mock 
      // also do smth. else 
     } 
    } 

Теперь у меня есть B b = new B(); и я хочу, чтобы проверить b.doSmthElse(), но мне нужно создать макет для a_instance объекта раньше, в противном случае я буду получать NullPointerException! Как я могу достичь этого с помощью EasyMock или PowerMock ???

+0

Что вы пытаетесь? Используете ли вы библиотеку или фреймворк зависимости? –

+0

Что значит? Yeap, в реальной жизни там вводится объект a_instance, но для модульного теста мне нужно его издеваться. – john

ответ

-1

Я не вижу причины, по которой здесь требуется PowerMock. Вы можете добиться этого с помощью EasyMock.

@Test 
public void testDoSmthElse() { 
    A a = EasyMock.createMock(A.class); 
    EasyMock.expect(a.doSmth()).andReturn(/*some value */); 
    EasyMock.replay(a); 

    B b = new B(); 
    Object whatever = b.doSmthElse(); 

    assert(); // psuedo-line. Add whatever assertion required 
} 

Примечание: Импорт соответствующие классы

+0

EasyMock.expect (a.doSmth()) // неприменим к void-методам !!! – john

+1

Замените эту строку просто 'a.doSmth();' и тест пройдет. – diegomtassis

+0

вам нужно ввести объект A в B до вызова b.doSmthElse() – maximus

0

Вы можете использовать

instanceName.methodName(); 
Easymock.expectLastCall(); //for void methods this is how it is done 

имя_экземпляра может быть издевались или actualInstance.

Если и может сделать статический метод, то это проще с powermock

Powermock.mockStatic(ClassNameContainingStaticMethod) 

Все статические методы получают издевались непосредственно

Предостережение: - Преобразование метод статики может иметь проблемы в других частях .Насторожно

Надеюсь, что это поможет. Все самое лучшее!

+1

'Easymock.expectLastCall();' не требуется. – diegomtassis

1
@Test 
public void testDoSomething() 
    { 
    // setup: sut 
    B b = new B(); 
    A mockA = EasyMock.createMock(A.class); 
    b.setA_instance(mockA); // If you have a setter 

    // setup: expectations 
    mockA.doSmth(); 

    // exercise 
    EasyMock.replay(mockA); 
    b.doSmthElse(); 

    // verify 
    EasyMock.verify(mockA); 
    } 

@Test 
public void testDoSomething_setUsingReflection() 
    { 
    // setup: sut 
    B b = new B(); 
    A mockA = EasyMock.createMock(A.class); 
    // Set the collaborator using a Spring reflection utility 
    ReflectionTestUtils.setField(b, "a_instance", mockA); 

    // setup: expectations 
    mockA.doSmth(); 

    // exercise 
    EasyMock.replay(mockA); 
    b.doSmthElse(); 

    // verify 
    EasyMock.verify(mockA); 
    } 
+0

Тогда мне нужно установить сеттер для a_instance, который (я имею в виду метод setter). Я собираюсь использовать только в тестовых целях. Не очень хорошая практика иметь код, который используется только для тестов внутри класса, который, например, содержит некоторую бизнес-логику. – john

+0

Это другая проблема, и есть много разных решений. Вы можете сделать публикацию соавтором, использовать рефлексию для ее установки или использовать такую ​​утилиту, как Spring [ReflectionTestUtils] (http://docs.spring.io/spring/docs/2.5.6/api/org/springframework/test/util/ ReflectionTestUtils.html). – diegomtassis

+0

Нет, отражение не будет работать, потому что я использую EasyMock для создания макета для класса B, и поэтому, если я попытаюсь получить это поле с использованием отражения, я получу NoSuchFieldException, потому что я понятия не имею, как это поле вызывается, когда макет создано. – john

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