我有一个私有的方法。现在,我不想在execute()
方法上进行单元测试时调用此私有方法。我已经尝试过PowerMockito和所有这些,但是所有类型的模拟它仍然进入私有方法。
请建议使用可行的测试用例。会很感激。
@Component
public class Employee implements SuperClass {
@Autowired
private FileTraverse fileTraverse;
@Override
public void execute() throws Exception {
List<String> traverse = fileTraverse.getFiles();
Boolean t = isFileTraversed(traverse);
}
private Boolean isFileTraversed(List<String> param1) {
Boolean flag;
//do some DB operation and return flag;
}
}
答案 0 :(得分:0)
@glytching是对的。它是在新服务/组件中提取方法并为其创建模拟的最佳变体。在这种情况下,您的代码是可测试的,您可以重复使用此组件...
但是,如果您只有一个用于此方法的用例,并且您不想仅为一个方法(辅助方法)创建服务/组件,则可以将方法可见性级别从私有更改为受保护或包默认。在这种情况下,您可以在子类中重写此方法以进行测试并使用此子类。你应该做什么: 为要测试的类创建子类,并使用此子类的实例而不是目标类。
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ServiceOverrideTestConfiguration.class)
public class MainServiceTest {
@Autowired
@Qualifier("subMainService") // or add @Primary and don't use Qualifier
private MainService service;
@Autowired
private SecondService secondService;
@Test
public void test(){
Object result = service.getResultFromMainService();
--here, method getResultFromMainService call inside the overrided
method that we can change
assertNotNull(result);
}
}
@ContextConfiguration
@Import(ApplicationConfigure.class)
class ServiceOverrideTestConfiguration {
@Bean("subMainService")
// or add @Primary and don't use Qualifier
MainService mainServiceSubBean(){
return new MainServiceUnderTest();
}
}
class MainServiceUnderTest extends MainService{
@Override
Object getResultFromMainServiceFromPrivate(){
return "SOME DEFAULT";
}
}
_
#Parallel function
runnable_X<-function(ID) {
require(R.utils)
Sys.sleep(ID)
return(ID)
}
!请注意,在极少数情况下,当您需要模拟/存根某些方法并且无法使用PowerMock或任何其他库时,请将此方法视为一种解决方法。更好,尝试重构并在代码中带来可测试性
答案 1 :(得分:0)
不要模仿私人方法。
请参阅以下建议:
SomeFunction
所以在isFileTraversed中 - 你将有一个数据库操作。此操作可能通过DAO / Repository对象执行。
所以你的代码可能会像:
@Component
public class Employee implements SuperClass {
@Autowired
private FileTraverse fileTraverse;
@Override
public void execute() throws Exception {
List<String> traverse = fileTraverse.getFiles();
Boolean t = isFileTraversed(traverse);
}
private Boolean isFileTraversed(List<String> param1) {
Boolean flag;
//do some DB operation and return flag;
}
}
您需要做的是模拟DatabaseAccessDao类上的公共checkFileTraversed()方法。
1)不要在字段上@Autowire - 更喜欢构造函数注入。
2)你确定要返回布尔值吗?允许“null”作为返回值吗?如果不是 - 考虑使用原始布尔类型;
答案 2 :(得分:0)
其他人都是对的。你应该尽量避免模仿私有方法。如果你真的需要模拟它,只需删除private
以将其置于默认范围内。
BUT
为了完整起见,您确实可以使用PowerMock。以下是使用PowerMock和EasyMock的示例。
public class Employee {
public void execute() {
// If our mock is working, isFileTraversed will return false
assertThat(isFileTraversed(Collections.emptyList())).isFalse();
}
private Boolean isFileTraversed(List<String> param1) {
return true;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(Employee.class)
public class EmployeeTest {
@Test
public void execute() throws Exception {
Employee employee = PowerMock.createPartialMockForAllMethodsExcept(Employee.class, "execute");
PowerMock.expectPrivate(employee, "isFileTraversed", Collections.emptyList()).andReturn(false);
PowerMock.replay(employee);
employee.execute();
PowerMock.verify(employee);
}
}