我有一个公共方法说a()
,它正在调用同一类中存在的私有方法B()
。
现在我的方法B
(私有)调用一个外部方法(比如search()
),它返回字符串列表。根据返回的列表;我必须在方法B
中执行一些逻辑。
当我使用一些列表值模拟外部方法调用(mock search
)时,mockito返回空列表;不是我在模拟这个外部呼叫时设置的列表。
我不明白为什么,我得到空名单。
以下是示例代码:
public class ABC {
@Autowired
private External ext;
// method 1
public void A(String id){
// method private call
B(id);
}
private String B(String id) {
// do something
// external method call
List myList = ext.search(id); // from here we getting empty list
if(myList != null &&
!myList.isEmpty()) {
// do some logic here,
}
}
}
Sample Test Class:
@RunWith(SpringJUnit4ClassRunner.class)
Class MyTest{
@Autowire
ABC abc;
@Test
public void myTest() {
// construct the mocked object
List resultList = new ArrayList();
resultList.add("Java");
resultList.add("C");
resultList.add("Python");
// mock the external API
Mockito.when(externalMock.search(Mockito.any(String.class)).
thenReturn(resultList);
// call method A on ABC class
abc.A(); // public method A call
}
}
// Mocked External class
@Profile("test")
@Configuration
public class ExternalMock {
@Bean
@Primary
public External getExternal() {
return Mockito.mock(External.class);
}
}
答案 0 :(得分:0)
因此,通常使用模拟框架的想法是替换类的依赖项,在本例中为External
,并使用简化的替换实现,以便您可以从测试中排除依赖项的行为。为此,您需要指定外部依赖项的接口,在您的情况下可能通过创建IExternal
接口并将其注入构造函数。当您实例化类的实际版本时,您可以传入实现External
的{{1}},并且在您的测试用例中,您可以传入IExternal
类的模拟实例。
以下是an article,其中包含使用Mockito将模拟依赖项注入类的示例。
答案 1 :(得分:0)
External
应明确注入主题类。
public class ABC {
private External ext;
@Autowire
public ABC(External ext) {
this.ext = ext;
}
// method 1
public void A(String id){
// method private call
B(id);
}
private String B(String id) {
// do something
// external method call
List myList = ext.search(id);
if(myList != null &&
!myList.isEmpty()) {
// ... do some logic here,
}
}
}
这样可以在单独测试时替换模拟。
public class MyTest {
@Test
public void myTest() {
//Arrange
List resultList = new ArrayList();
resultList.add("Java");
resultList.add("C");
resultList.add("Python");
// mock the external API
External externalMock = Mockito.mock(External.class);
Mockito.when(externalMock.search(Mockito.anyString()).thenReturn(resultList);
ABC abc = new ABC(externalMock);
String input = "Hello world";
//Act
abc.A(input); // public method A call
//Assert
//...
}
}