Zrobiłem sporo wyszukiwania w Internecie i nie mogę znaleźć przykładu testów jednostkowych z autowyred konstruktorem. Używam Springa do autoprzesyłania wartości z pliku właściwości do mojej aplikacji. Chcę przetestować metodę startową MyApp.java, ale mam autowyreduktora, więc nie wiem, jak utworzyć instancję MyApp. Bez autowired właściwości, robiłam to w moim badanej jednostki:Jak mogę JUnit przetestować konstruktor autiosered Spring?
@Test
public void testStart() {
try{
MyApp myApp = new MyApp();
myApp.start();
}
catch (Exception e){
fail("Error thrown")
}
}
ja nie chcę mock autowiring, jak trzeba uzyskać wartości z pliku właściwości oraz dodatkowo komplikować, jestem konfigurowanie wszystkiego za pomocą adnotacji. Nie mam pliku spring.xml, application-context.xml ani web.xml. Jak więc zrobić prezentację/testować metodę uruchamiania MyApp? Próbowałem dodać w @RunWith (SpringJUnit4ClassRunner.class) i autowiring MyApp myApp, ale generuje błędy dotyczące nie załadowania kontekstu aplikacji, które nie są ustalone przez implementację ApplicationContextAware w klasie testowej.
Oto MyApp.java
@Component
public class MyApp {
private static ApplicationContext applicationContext;
private static MyAppProperties myAppProperties;
//Obtain the values from the app.properties file
@Autowired
MyApp(MyAppProperties myAppProps){
myAppProperties = myAppProps;
}
public static void main(String[] args) throws Exception {
// Instantiate the application context for use by the other classes
applicationContext = new AnnotationConfigApplicationContext("com.my.company");
start();
}
/**
* Start the Jetty server and configure the servlets
*
* @throws Exception
*/
public static void start() throws Exception {
// Create Embedded Jetty server
jettyServer = new Server();
// Configure Jetty so that it stops at JVM shutdown phase
jettyServer.setStopAtShutdown(true);
jettyServer.setStopTimeout(7_000);
// Create a list to hold all of the handlers
final HandlerList handlerList = new HandlerList();
// Configure for Http
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(myAppProperties.getHTTP_SECURE_PORT());
....
}
}
Tutaj jest złożyć moje app.properties
# Spring Configuration for My application
#properties for the embedded jetty server
http_server_port=12345
Oto MyAppProperties.java
@Component
public class MyAppProperties implements ApplicationContextAware {
private ApplicationContext applicationContext;
//List of values from the properties files to be autowired
private int HTTP_SERVER_PORT;
...
@Autowired
public MyAppProperties(@Value("${http_server_port}") int http_server_port, ...){
this.HTTP_SERVER_PORT = http_server_port;
}
/**
* @return the applicationContext
*/
public ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* @param applicationContext
* the applicationContext to set
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* @param name
* the name to set
*/
public void setHTTP_SERVER_PORT(String name) {
JETTY_SERVER_NAME = name;
}
/**
* @return the httpServerPort
*/
public int getHTTP_SERVER_PORT() {
return HTTP_SERVER_PORT;
}
}
Oto MyAppTest.java
@RunWith(SpringJUnit4ClassRunner.class)
public class MyAppTest implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext appContext) {
applicationContext = appContext;
}
@Autowired
private MyApp myapp;
@Test
public void testStart(){
try {
if(myapp != null){
myapp.start();
}
else{
fail("myapp is null");
}
} catch (Exception e) {
fail("Error thrown");
e.printStackTrace();
}
}
}
UPDATE: Oto moja klasa konfiguracja
@Configuration
@Component
public class ApplicationConfig implements ApplicationContextAware {
private final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfig.class);
private ApplicationContext applicationContext;
/**
* @return the applicationContext
*/
public ApplicationContext getApplicationContext() {
LOGGER.debug("Getting Application Context", applicationContext);
return applicationContext;
}
/**
* @param applicationContext
* the applicationContext to set
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
// Needed for @Value
/**
* Property sources placeholder configurer.
*
* @return the property sources placeholder configurer
*/
@Bean
public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
propertyPlaceholderConfigurer.setLocation(new ClassPathResource("app.properties"));
return propertyPlaceholderConfigurer;
}
...
}
Dodanie tylko '@ RunWith' i bez informowania, która konfiguracja do załadowania zakończy się niepowodzeniem. Musisz dodać "public static class" do swojej klasy testowej, wstawiając '@ Configuration' i' @ComponentScan ("your.package") '. Na wyższym poziomie sugerowałbym użycie Spring Boot również do bootstrapu aplikacji i wstrzykiwania/używania właściwości, ponieważ wydaje się, że robisz dokładnie to, co Spring Boot zapewnia natychmiast po uruchomieniu (włączając w to wsparcie testowe dla niego). –
@ M.Deinum Niestety, Spring Boot nie jest rozwiązaniem dla mnie z powodu konfliktów z innymi narzędziami. Żeby wyjaśnić, czy mówisz, że powinienem zmienić swoją klasę testową na publiczną klasę statyczną MyAppTest, czy powinienem zrobić kolejną klasę? Kiedy próbuję utworzyć stateczność klasy MyAppTest, pojawia się komunikat o błędzie z informacją, że jest to niedozwolony modyfikator. – jencoston
Nie trzeba dodawać wewnętrznej klasy konfiguracji.Nie widzę też żadnej różnicy w tym, co Spring Boot robi ze śmiechem z wewnętrznego serwera, tak jak ty sam, tak naprawdę nie powinno być żadnej różnicy. –