Mockito: макет инициализации частного поля

Как я могу издеваться над переменной поля, которая инициализируется inline?

например

class Test {
    private Person person = new Person();
    ...
    public void testMethod() {
        person.someMethod();
        ...
    }
}

здесь я хочу поглумиться человек.someMethod () при тестировании метода -

5 ответов


Mockito поставляется с вспомогательным классом, чтобы сэкономить Ваше отражение котла пластину код:

import org.mockito.internal.util.reflection.Whitebox;

//...

@Mock
private Person mockedPerson;
private Test underTest;

// ...

@Test
public void testMethod() {
    Whitebox.setInternalState(underTest, "person", mockedPerson);
    // ...
}

обновление: К сожалению, команда mockito решила удалить класс в Mockito 2. Таким образом, вы вернулись к написанию собственного кода шаблона отражения, используйте другую библиотеку (например,Apache Commons Lang), или просто уворовали Whitebox класса (MIT licensed).


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

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Test.class })
public class SampleTest {

@Mock
Person person;

@Test
public void testPrintName() throws Exception {
    PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
    Test test= new Test();
    test.testMethod();
    }
}

ключевыми моментами этого решения являются:

  1. запуск моих тестовых случаев с PowerMockRunner:@RunWith(PowerMockRunner.class)

  2. поручите Powermock подготовить Test.class для манипуляции частными полями:@PrepareForTest({ Test.class })

  3. и, наконец, издеваться над конструктором для человека класс:

    PowerMockito.mockStatic(Person.class); PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);


очень опоздала на вечеринку, но я был поражен, вот и получил помощь от друга. Дело было не в том, чтобы использовать PowerMock. Это работает с последней версией Mockito.

Mockito поставляется с этим org.mockito.internal.util.reflection.FieldSetter.

то, что он в основном делает, помогает вам изменять частные поля с помощью отражения.

вот как вы его используете -

@Mock
private Person mockedPerson;
private Test underTest;

// ...

@Test
public void testMethod() {
    FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person", mockedPerson);
    // ...
    verify(mockedPerson).someMethod()

}

таким образом, вы можете передать макет объекта, а затем проверить его позже.

ссылки:

https://www.codota.com/code/java/methods/org.mockito.internal.util.reflection.FieldSetter/set


может быть много способов, один из них может быть

Class Test {
  private Person person = new Person();
  ...
  public void testMethod() {
    person.someMethod();
    ...
  }
}

Это должно быть изменено, так как

Class Test {
  private Person person;
  public Test() {
      if(person == null) {
         person = new Person();
      }
  }
  ...
  public void testMethod() {
    person.someMethod();
    ...
  }

}

в вашем тесте,

@Runwith(SpringJunit4Runner.class)
public class TestingTest {

@InjectMocks
Test test;

@Mock
private Person person;

@Before
public void setUp() {

when(person.XXX).thenReturn("");

}

@Test
public void testMethod() {

...........
}
}

следующий код можно использовать для инициализации mapper в макете клиента REST. The mapper поле является частным и должно быть установлено во время установки модульного теста.

import org.mockito.internal.util.reflection.FieldSetter;

new FieldSetter(client, Client.class.getDeclaredField("mapper")).set(new Mapper());