When we know the required feature, we will start looking at the Alexandria project:
- 15 files
- Gradle-based (build.gradle)
- 0 tests
Firstly, we want to confirm that this project has never been tested, and the lack of a test folder reveals so:
$ find src/test find: src/test: No such file or directory
These are the folder contents for the Java part:
$ cd src/main/java/com/packtpublishing/tddjava/ch09/alexandria/ $ find . . ./Book.java ./Books.java ./BooksEndpoint.java ./BooksRepository.java ./CustomExceptionMapper.java ./MyApplication.java ./States.java ./User.java ./UserRepository.java ./Users.java
Here is the rest:
$ cd src/main $ find resources webapp resources resources/applicationContext.xml webapp webapp/WEB-INF webapp/WEB-INF/web.xml
This seems to be a web project (indicated by the web.xml file) using Spring (indicated by the applicationContext.xml). The dependencies in the build.gradle show the following (fragment):
compile 'org.springframework:spring-web:4.1.4.RELEASE'
Having Spring is already a good sign, as it can help with the dependency injection, but a quick look showed that the context is not really being used. Maybe something that was used in the past?
In the web.xml file, we can find this fragment:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <module-name>alexandria</module-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <servlet> <servlet-name>SpringApplication</servlet-name> <servlet-class>
org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.packtpublishing.tddjava.alexandria.MyApplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
In this file, we discover the following:
- The context in applicationContext.xml will be loaded
- There is an application file (com.packtpublishing.tddjava.alexandria.MyApplication) that will be executed inside a servlet
The MyApplication file is as follows:
public class MyApplication extends ResourceConfig { public MyApplication() { register(RequestContextFilter.class); register(BooksEndpoint.class); register(JacksonJaxbJsonProvider.class); register(CustomExceptionMapper.class); } }
This configures the necessary classes for executing the BooksEndpoint endpoint (fragment):
@Path("books") @Component public class BooksEndpoint {
private BooksRepository books = new BooksRepository(); private UserRepository users = new UserRepository();
In this last snippet, we can find one of the first indicators that this is a legacy codebase—both dependencies (books and users) are created inside the endpoint and not injected. This makes unit testing more difficult.
We can start by writing down the element that will be used during refactoring; we write the code for the dependency injection in BooksEndpoint.