The only thing that does not fully convince me in your articles is usage of Guice. I'm currently unable to see clearly its advantages over plain factories, crafted by hand. Do you recommend using of Guice in every single case? I strongly suspect, there are cases, where hand-crafted factories make a better fit than Guice. Could you comment on that (possibly at your website)?
Hi Misko, First I would like to thank you for the “Guide to Writing Testable Code”, which really helped me to think about better ways to organize my code and architecture. Trying to apply the guide to the code I’m working on, I came up with some difficulties. Our code is based on external frameworks and libraries. Being dependent on external frameworks makes it harder to write tests, since test setup is much more complex. It’s not just a single class we’re using, but rather a whole bunch of classes, base classes, definitions and configuration files. Can you provide some tips about using external libraries or frameworks, in a manner that will allow easy testing of the code? -- Thanks, Shahar
interface Authenticator { boolean authenticate(String username, String password); }
class LoginPage { Authenticator authenticator; boolean success; String errorMessage; LoginPage(Authenticator authenticator) { this.authenticator = authenticator; } String execute(Map<String, String> parameters, String cookie) { // do some work success = ...; errorMessage = ...; } String render(Writer writer) { if (success) return "redirect URL"; else writer.write(...); } }
class LoginServlet extends HttpServlet { Provider<LoginPage> loginPageProvider; // no arg constructor required by // Servlet Framework LoginServlet() { this(Global.injector .getProvider(LoginPage.class)); } // Dependency injected constructor used for testing LoginServlet(Provider<LoginPage> loginPageProvider) { this.loginPageProvider = loginPageProvider; } service(HttpServletRequest req, HttpServletResponse resp) { LoginPage page = loginPageProvider.get(); page.execute(req.getParameterMap(), req.getCookies()); String redirect = page.render(resp.getWriter()) if (redirect != null) resp.sendRedirect(redirect); } }