我有一个使用SpringBoot进行依赖注入的应用程序,应用程序工作正常,但测试失败,因为@Autowired字段在测试期间没有被注入。
@SpringBootApplication
public class ProcessorInterface {
protected final static Logger logger = Logger.getLogger( ProcessorInterface.class );
public static void main(String[] args) {
try {
SpringApplication.run(ProcessorInterfaceRunner.class, args);
} catch (Exception ex) {
logger.error("Error running ProcessorInterface", ex);
}
}
}
@Component
@Configuration
@ComponentScan
public class ProcessorInterfaceRunner implements CommandLineRunner {
protected final static Logger logger = Logger.getLogger( ProcessorInterface.class );
@Autowired
private RequestService requestService = null;
@Autowired
private ValidatorService validatorService = null;
@Override
public void run(String... args) throws Exception {
ESPOutTransaction outTransaction = null;
outTransaction = new ESPOutTransaction();
// initialize outTransaction fields
...
// done initializing outTransaction fields
if (validatorService.isValid(outTransaction)) {
System.out.println(requestService.getRequest(outTransaction));
} else {
System.out.println("Bad Data");
}
}
}
@Service
public class ESPRequestService implements RequestService<ESPOutTransaction> {
@Autowired
ValidatorService validatorService = null;
@Override
public String getRequest(ESPOutTransaction outTransaction) throws IllegalArgumentException {
if (!validatorService.isValid(outTransaction)) {
throw new IllegalArgumentException("Invalid parameters in transaction object. " + outTransaction.toString());
}
StringBuffer buff = new StringBuffer("create request XML");
buff.append("more XML");
return buff.toString();
}
}
@Service
public class ESPValidatorService implements ValidatorService {
private static org.apache.log4j.Logger logger = Logger.getLogger(ESPValidatorService.class);
// declare some constants for rules
private static final int MAX_LENGTH_XYZ = 3;
@Override
public boolean isValid(OutTransaction outTransaction) {
ESPOutTransaction espOutTransaction = (ESPOutTransaction)outTransaction;
boolean isValid = true;
if (espOutTransaction == null) {
logger.warn("espOutTransaction is NULL");
isValid = false;
} else {
// XYZ is required
if (espOutTransaction.getXYZ() == null) {
logger.warn("XYZis NULL\r\n" + espOutTransaction.toString());
isValid = false;
}
// XYZ max length = MAX_LENGTH_XYZ
if (espOutTransaction.getXYZ() != null && espOutTransaction.getPubCode().trim().length() > MAX_LENGTH_XYZ) {
logger.warn("XYZis too long (max length " + MAX_LENGTH_XYZ + ")\r\n" + espOutTransaction.toString());
isValid = false;
}
}
return isValid;
}
}
当我运行应用程序时,这些都可以正常工作并获得良好的输出。当我尝试测试时,它失败了,因为它无法找到ESPValidatorService注入ESPRequestService
@RunWith(Suite.class)
@SuiteClasses({ ESPOutTransactionValidatorTest.class, ESPRequestTest.class })
public class AllTests {}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ESPRequestService.class})
public class ESPRequestTest {
@Test
public void testGetRequest() {
ESPRequestService requestService = new ESPRequestService();
String XYZ = "XYZ";
ESPOutTransaction outTransaction = null;
outTransaction = new ESPOutTransaction();
outTransaction.setXYZ(XYZ);
String strRequest = "some expected request XML";
String request = requestService.getRequest(outTransaction);
assertEquals(request, strRequest);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ESPValidatorService.class)
public class ESPOutTransactionValidatorTest {
@Test
public void testIsValid() {
ESPValidatorService validatorService = new ESPValidatorService();
ESPOutTransaction outTransaction = null;
// test request = null
assertFalse(validatorService.isValid(outTransaction));
String XYZ = "XYZ";
outTransaction = new ESPOutTransaction();
outTransaction.setXYZ(XYZ);
// test all good
assertTrue(validatorService.isValid(outTransaction));
// test XYZ
outTransaction.setXYZ(null);
assertFalse(validatorService.isValid(outTransaction));
outTransaction.setXYZ("ABCD"); // too long
assertFalse(validatorService.isValid(outTransaction));
outTransaction.setXYZ(XYZ);
}
}
如何让单元测试自动接线?
答案 0 :(得分:2)
我看到两个问题:
1)您不依赖于Spring bean,而是使用new
运算符创建实例。
而不是写作:
ESPRequestService requestService = new ESPRequestService();
你应该让Spring注入实例:
@Bean
ESPRequestService requestService;
2)@SpringBootTest
配置不正确。
在每个测试中,您在classes
的{{1}}属性中指定了一个非常具体的bean类:
@SpringBootTest
和
@SpringBootTest(classes = ESPValidatorService.class)
public class ESPOutTransactionValidatorTest {
但@SpringBootTest(classes = {ESPRequestService.class})
public class ESPRequestTest {
的{{1}}属性用于指定用于加载ApplicationContext的带注释的类。
用于加载ApplicationContext的带注释的类。能够 也可以使用
classes
指定。如果不 定义了显式类,测试将查找嵌套@SpringBootTest
课程,然后再回到@ContextConfiguration(classes=...)
搜索。
因此,可能无法在Spring容器中发现和加载应用程序的所有配置类和bean。
为了能够在测试期间加载所有应用程序bean,最简单的方法是不在@Configuration
注释中指定SpringBootConfiguration
属性:
classes
它将查找包含@SpringBootTest
的Spring bean
理想情况下,它会找到您应用程序的@SpringBootTest
public class ESPRequestTest { ...}
bean
如果测试类的包位于@SpringBootConfiguration
类的包(或更低级别)内,则应自动发现它。
否则另一种方法是指定一个允许加载所有必需bean的配置:
@SpringBootApplication