#junit #mocking #mockito
#junit #издевательство #mockito
Вопрос:
Я хочу протестировать функцию, внутри которой есть вызов другой функции (которая принимает два параметра) Я хочу издеваться над этой внутренней функцией.Но у меня возникают трудности с тем, что передать в качестве параметра
void func(classA a,classB b)
{
List<ClassC> list= Objd.func2(a.getSome(),b)
///some other things
}
теперь я хочу издеваться над этой func2 , у меня уже есть интерфейс для класса obj C.
Я попытался использовать
InterfaceClassD objD=Mockito.mock(InterfaceClassD.class)
Mockito.when(obj.func2(a.getsome(),b)).thenreturn(null);
но это не работает, выполняется func2
Я даже пытался
InterfaceClassD objD=Mockito.mock(InterfaceClassD.class)
Mockito.when(obj.func2(anyList(),any(classB.class)).thenreturn(null);
ПРИМЕЧАНИЕ — a.getSome() возвращает список
, но он тоже не работает, выполняется func2
Комментарии:
1. Является
func2
ли статический метод вObjd
классе?2. нет, это не статический метод. вы можете рассматривать Objd как объект класса ClassD
Ответ №1:
Трудно ответить на этот вопрос без дополнительного контекста.
Откуда в функции «func» берется ссылка на «Objd»? Где она объявлена?
Создание и использование mocks в тесте состоит из двух этапов:
- создание макета
- внедрение макета
«Внедрение макета» относится к (каким-то образом) замене ссылки на реальный объект, который будет использовать функция, на макет версии, которую вы создали с помощью Mockito.
Пример:
// Class under test
public class Foo {
// this is the object we need to mock
private InterfaceClassD objD;
void func(classA a,classB b) {
// here is where we use "objD"
List<ClassC> list= objD.func2(a.getSome(),b)
///some other things
}
}
Чтобы написать тест с макетом objD, вы должны заменить «реальный» objD на макет непосредственно перед вызовом тестируемого метода (функции).
Обычно это делается либо с помощью внедрения конструктора, либо с помощью установки, либо с помощью аннотаций Mockito.
Пример с внедрением конструктора:
// Class under test
public class Foo {
// this is the object we need to mock
private InterfaceClassD objD;
// constructor injection
public Foo(InterfaceClassD objD) {
this.objD = objD;
}
void func(classA a,classB b) {
// here is where we use "objD"
List<ClassC> list= objD.func2(a.getSome(),b);
///some other things
}
}
// Unit test
public class FooTest {
@Test
public void someTest() {
// create the mock:
InterfaceClassD mock = Mockito.mock(InterfaceClassD.class);
// inject the mock:
Foo foo = new Foo(objD);
// test: this should call method func but use the mock
foo.func(dummyA, dummyB);
// verify/assert something...
}
}
Пример использования внедрения установщика:
// Class under test
public class Foo {
// this is the object we need to mock
private InterfaceClassD objD;
// setter injection
public void setInterfaceClassD(InterfaceClassD objD) {
this.objD = objD;
}
void func(classA a,classB b) {
// here is where we use "objD"
List<ClassC> list= objD.func2(a.getSome(),b);
///some other things
}
}
// Unit test
public class FooTest {
@Test
public void someTest() {
// create the mock:
InterfaceClassD mock = Mockito.mock(InterfaceClassD.class);
Foo foo = new Foo();
// inject the mock:
foo.setInterfaceClassD(mock);
// test: this should call method func but use the mock
foo.func(dummyA, dummyB);
// verify/assert something...
}
}
Пример использования аннотаций Mockito и JUnit 5:
// Class under test
public class Foo {
// this is the object we need to mock
private InterfaceClassD objD;
void func(classA a,classB b) {
// here is where we use "objD"
List<ClassC> list= objD.func2(a.getSome(),b);
///some other things
}
}
// Unit test
// Note the Mockito extension annotation.
@ExtendWith(MockitoExtension.class)
public class FooTest {
// the Mockito JUnit extension will instantiate this automagically.
// The name of the mock must exactly match the name of the field in
// containing class.
private @Mock InterfaceClassD objD;
// Mockito annotation processing will create an instance of Foo, and
// replace any of its fields with any mocks that have the same name
// and type. In this case, objD.
private @InjectMocks Foo foo;
@Test
public void someTest() {
// Just use it.
// test: this should call method func but use the mock
foo.func(dummyA, dummyB);
// verify/assert something...
}
}