Wie kann ich den JUnit-test eine Feder autowired Konstruktor?
Habe ich einiges geschafft, der online-Suche und ich kann nicht finden, ein Beispiel-unit-Tests mit einem autowired-Konstruktor. Ich bin mit Spring zu autowire in den Werten aus einer properties-Datei meiner Anwendung. Ich will unit-Tests MyApp.java's start-Methode, aber ich habe eine autowired-Konstruktor, also ich weiß nicht, wie zu instanziieren Anwendung. Ohne die autowired Eigenschaften, ich Tat dies in meinem unit-test:
@Test
public void testStart() {
try{
MyApp myApp = new MyApp();
myApp.start();
}
catch (Exception e){
fail("Error thrown")
}
}
Ich nicht wollen, zu verspotten, das autowiring, wie ich brauche, um die Werte aus der properties-Datei und um weitere Dinge zu komplizieren, ich bin der Konfiguration alles durch Anmerkungen. Ich habe nicht ein spring.xml, application-context.xml oder eine web.xml Datei. Also, wie gehe ich über die Instanziierung/Test-Anwendung-start-Methode? Ich versucht, indem in der @RunWith(SpringJUnit4ClassRunner.class) und autowiring MyApp myApp, aber es wirft Fehler, zu scheitern, um die Anwendung laden Zusammenhang, die nicht behoben durch die Umsetzung ApplicationContextAware auf der test-Klasse.
Hier 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());
....
}
}
Hier ist meine app.Eigenschaften Datei
# Spring Configuration for My application
#properties for the embedded jetty server
http_server_port=12345
Hier 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;
}
}
Hier 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: Hier ist meine Konfiguration, Klasse
@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;
}
...
}
- Nur hinzufügen
@RunWith
und ohne die Konfiguration zu laden, wird fehlschlagen. Sie haben, um einepublic static class
zu Ihrem test-Klasse@Configuration
und@ComponentScan("your.package")
auf Sie. Auf einer weiteren Ebene würde ich vorschlagen, mit Spring Boot zu bootstrap-Ihre Anwendung und Spritzen/nutzen-Eigenschaften, wie Sie scheinen zu tun genau das, was Spring Boot bietet out-of-the-box (einschließlich test-Unterstützung). - Leider, Spring Boot nicht eine option für mich aufgrund von Konflikten mit anderen tools. Nur zur Klarstellung sagen Sie, dass ich das ändern sollte meiner test-Klasse public static class MyAppTest oder soll ich zu einer anderen Klasse? Wenn ich versuche, die MyAppTest Klasse statische erhalte ich eine Fehlermeldung, die besagt, dass es eine illegale modifier.
- Nein, Sie brauchen, um hinzuzufügen, eine interne configuration-Klasse. Auch ich sehe keinen Unterschied in dem, was Spring Boot macht mit lachen einem internen server wie Sie selbst, es sollte nicht wirklich einen Unterschied.
- Ich habe bereits eine configuration-Klasse, sorry, ich vergaß zu berücksichtigen. Ich habe bearbeitet die Frage, um es hinzuzufügen. Können Sie bitte erklären, was du meinst "lacht einem internen server"? Ich habe noch nie gehört, dass Satz vor.
- Das war auto-correct. Ich meinte natürlich starten und nicht lachen.
- Dann nutzen Sie
@ContextConfiguration
auf Ihrem test-Klasse zum laden derApplicationConfig
. Auch IhregetPropertyPlaceholderConfigurer
sollte eine statische Methode. - Ja, das hat funktioniert! Danke!!! Wenn Sie schreiben, eine Antwort werde ich akzeptieren Sie es als richtig.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können wir mock-Objekte mit den jmockito Rahmen.
Mit @InjectMocks für dependency-injection über Mockito
Sie haben auch die @InjectMocks annotation, die versucht zu tun, Konstruktor, Methode oder Feld dependency injection, basierend auf dem Typ. Der folgende code ist ein leicht modifiziertes Beispiel aus der Javadoc.
Folgenden werden die unit-test-Klasse.
}
Stellen Sie sicher, dass Sie mit @RunWith(MockitoJUnitRunner.class)
Weitere Informationen finden Sie unter http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/InjectMocks.html.