package org.jooby.servlet;
import static org.easymock.EasyMock.expect;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jooby.Jooby;
import org.jooby.spi.HttpHandler;
import org.jooby.test.MockUnit;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.typesafe.config.Config;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ServletHandler.class, ServletServletRequest.class, ServletServletResponse.class })
public class ServletHandlerTest {
MockUnit.Block init = unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
Config config = unit.mock(Config.class);
expect(config.getString("application.tmpdir")).andReturn("target");
Jooby app = unit.mock(Jooby.class);
expect(app.require(HttpHandler.class)).andReturn(dispatcher);
expect(app.require(Config.class)).andReturn(config);
ServletContext ctx = unit.mock(ServletContext.class);
expect(ctx.getAttribute(Jooby.class.getName())).andReturn(app);
ServletConfig servletConfig = unit.get(ServletConfig.class);
expect(servletConfig.getServletContext()).andReturn(ctx);
};
@Test
public void initMethodMustAskForDependencies() throws Exception {
new MockUnit(ServletConfig.class, HttpHandler.class)
.expect(init)
.run(unit ->
new ServletHandler()
.init(unit.get(ServletConfig.class))
);
}
@Test
public void serviceShouldDispatchToHandler() throws Exception {
new MockUnit(ServletConfig.class, HttpHandler.class, HttpServletRequest.class,
HttpServletResponse.class)
.expect(init)
.expect(
unit -> {
HttpHandler dispatcher = unit.get(HttpHandler.class);
ServletServletRequest req = unit.mockConstructor(ServletServletRequest.class,
new Class[]{HttpServletRequest.class, String.class },
unit.get(HttpServletRequest.class), "target");
ServletServletResponse rsp = unit.mockConstructor(ServletServletResponse.class,
new Class[]{HttpServletRequest.class, HttpServletResponse.class },
unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
dispatcher.handle(req, rsp);
})
.run(unit -> {
ServletHandler handler = new ServletHandler();
handler.init(unit.get(ServletConfig.class));
handler.service(unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
});
}
@Test(expected = IllegalStateException.class)
public void serviceShouldCatchExceptionAndRethrowAsRuntime() throws Exception {
HttpHandler dispatcher = (request, response) -> {
throw new Exception("intentional err");
};
new MockUnit(ServletConfig.class, HttpServletRequest.class,
HttpServletResponse.class)
.expect(unit -> {
Config config = unit.mock(Config.class);
expect(config.getString("application.tmpdir")).andReturn("target");
Jooby app = unit.mock(Jooby.class);
expect(app.require(HttpHandler.class)).andReturn(dispatcher);
expect(app.require(Config.class)).andReturn(config);
ServletContext ctx = unit.mock(ServletContext.class);
expect(ctx.getAttribute(Jooby.class.getName())).andReturn(app);
ServletConfig servletConfig = unit.get(ServletConfig.class);
expect(servletConfig.getServletContext()).andReturn(ctx);
})
.expect(unit -> {
unit.mockConstructor(ServletServletRequest.class,
new Class[]{HttpServletRequest.class, String.class },
unit.get(HttpServletRequest.class), "target");
unit.mockConstructor(ServletServletResponse.class,
new Class[]{HttpServletRequest.class, HttpServletResponse.class },
unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
})
.expect(unit -> {
HttpServletRequest req = unit.get(HttpServletRequest.class);
expect(req.getRequestURI()).andReturn("/");
})
.run(unit -> {
ServletHandler handler = new ServletHandler();
handler.init(unit.get(ServletConfig.class));
handler.service(unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
});
}
@Test(expected = IOException.class)
public void serviceShouldCatchIOExceptionAndRethrow() throws Exception {
HttpHandler dispatcher = (request, response) -> {
throw new IOException("intentional err");
};
new MockUnit(ServletConfig.class, HttpServletRequest.class,
HttpServletResponse.class)
.expect(unit -> {
Config config = unit.mock(Config.class);
expect(config.getString("application.tmpdir")).andReturn("target");
Jooby app = unit.mock(Jooby.class);
expect(app.require(HttpHandler.class)).andReturn(dispatcher);
expect(app.require(Config.class)).andReturn(config);
ServletContext ctx = unit.mock(ServletContext.class);
expect(ctx.getAttribute(Jooby.class.getName())).andReturn(app);
ServletConfig servletConfig = unit.get(ServletConfig.class);
expect(servletConfig.getServletContext()).andReturn(ctx);
})
.expect(unit -> {
unit.mockConstructor(ServletServletRequest.class,
new Class[]{HttpServletRequest.class, String.class },
unit.get(HttpServletRequest.class), "target");
unit.mockConstructor(ServletServletResponse.class,
new Class[]{HttpServletRequest.class, HttpServletResponse.class },
unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
})
.expect(unit -> {
HttpServletRequest req = unit.get(HttpServletRequest.class);
expect(req.getRequestURI()).andReturn("/");
})
.run(unit -> {
ServletHandler handler = new ServletHandler();
handler.init(unit.get(ServletConfig.class));
handler.service(unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
});
}
@Test(expected = ServletException.class)
public void serviceShouldCatchServletExceptionAndRethrow() throws Exception {
HttpHandler dispatcher = (request, response) -> {
throw new ServletException("intentional err");
};
new MockUnit(ServletConfig.class, HttpServletRequest.class,
HttpServletResponse.class)
.expect(unit -> {
Config config = unit.mock(Config.class);
expect(config.getString("application.tmpdir")).andReturn("target");
Jooby app = unit.mock(Jooby.class);
expect(app.require(HttpHandler.class)).andReturn(dispatcher);
expect(app.require(Config.class)).andReturn(config);
ServletContext ctx = unit.mock(ServletContext.class);
expect(ctx.getAttribute(Jooby.class.getName())).andReturn(app);
ServletConfig servletConfig = unit.get(ServletConfig.class);
expect(servletConfig.getServletContext()).andReturn(ctx);
})
.expect(unit -> {
unit.mockConstructor(ServletServletRequest.class,
new Class[]{HttpServletRequest.class, String.class },
unit.get(HttpServletRequest.class), "target");
unit.mockConstructor(ServletServletResponse.class,
new Class[]{HttpServletRequest.class, HttpServletResponse.class },
unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
})
.expect(unit -> {
HttpServletRequest req = unit.get(HttpServletRequest.class);
expect(req.getRequestURI()).andReturn("/");
})
.run(unit -> {
ServletHandler handler = new ServletHandler();
handler.init(unit.get(ServletConfig.class));
handler.service(unit.get(HttpServletRequest.class), unit.get(HttpServletResponse.class));
});
}
}