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();
}
}
ключевыми моментами этого решения являются:
запуск моих тестовых случаев с PowerMockRunner:
@RunWith(PowerMockRunner.class)
поручите Powermock подготовить
Test.class
для манипуляции частными полями:@PrepareForTest({ Test.class })
-
и, наконец, издеваться над конструктором для человека класс:
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());