Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
JUnit In Action.pdf
Скачиваний:
15
Добавлен:
20.05.2015
Размер:
16.4 Mб
Скачать

204CHAPTER 9

Unit-testing servlets and filters

throw new ServletException(

"Failed to execute command", e);

}

}

}

There are two points of note. First, the call to callView is not present in doGet; the tests don’t yet mandate it. (They will, but not until you write the unit tests for your JSP.) Second, you throw a RuntimeException object if executeCommand is called. You could return null, but throwing an exception is a better practice. An exception clearly states that you have not implemented the method. If the method is called by mistake, there won’t be any surprises.

JUnit best practice: throw an exception for methods that aren’t implemented

When you’re writing code, there are often times when you want to execute the code without having finished implementing all methods. For example, if you’re writing a mock object for an interface and the code you’re testing uses only one method, you don’t need to mock all methods. A very good practice is to throw an exception instead of returning null values (or not returning anything for methods with no return value). There are two good reasons: Doing this states clearly to anyone reading the code that the method is not implemented and ensures that if the method is called, it will behave in such a way that you cannot mistake skeletal behavior for real behavior.

9.3 Testing servlets with mock objects

You have seen how to write servlet unit tests using Cactus. Let’s try to do the same exercise using only a mock-objects approach. We’ll then define some rules for deciding when to use the Cactus approach and when to use mock objects.

In chapter 8, you used EasyMock to write mock objects. This time you’ll use the DynaMock API, which is part of the MockObjects.com framework (http:// www.mockobjects.com/). They both use Dynamic Proxies to generate mock objects at runtime. However, the DynaMock framework has several advantages over EasyMock: Its API is more comprehensive (notably in the definition of the expectations), and it results in more concise code. The downside is that it’s slightly more complex to use (at least initially), and it’s a less mature framework. (However, we haven’t resisted the temptation to show you how to use it, because we think it has a great future.)

Testing servlets with mock objects

205

 

 

EasyMock vs. DynaMock

DynaMock provides more concise code (about half as much code as EasyMock).

EasyMock provides strong typing, which is useful for auto-completion and when interfaces change.

DynaMock has a more comprehensive API (especially for expectations).

EasyMock is more mature, because it has been around for several years. DynaMock is very new, and its API is not completely stabilized (as of this writing).

9.3.1Writing a test using DynaMocks and DynaBeans

Listing 9.9 shows the re-implementation of testGetCommandOk and testGetCommandNotDefined from listing 9.1.

Listing 9.9 Tests for AdminServlet.getCommand using the DynaMock API

package junitbook.servlets;

[...]

import com.mockobjects.dynamic.C; import com.mockobjects.dynamic.Mock;

public class TestAdminServletMO extends TestCase

{

private Mock mockRequest;

private HttpServletRequest request; private AdminServlet servlet;

protected void setUp()

{

servlet = new AdminServlet();

mockRequest = new Mock(HttpServletRequest.class); request = (HttpServletRequest) mockRequest.proxy();

}

protected void tearDown()

{

mockRequest.verify();

}

public void testGetCommandOk() throws Exception

{

mockRequest.expectAndReturn("getParameter", "command", "SELECT...");

b

c

d

206CHAPTER 9

Unit-testing servlets and filters

String command = servlet.getCommand(request);

assertEquals("SELECT...", command);

}

public void testGetCommandNotDefined()

{

mockRequest.expectAndReturn("getParameter", C.isA(String.class), null);

try

{

servlet.getCommand(request); fail("Command should not have existed");

}

catch (ServletException expected)

{

assertTrue(true);

}

}

}

e

bYou’re using an HttpServletRequest object in the code to test; so, because you aren’t running inside a container, you need to create a mock for it. Here you tell

the DynaMock API to generate an HttpServletRequest mock for you.

cAsk your mock to verify the expectations you have set on it and to verify that the methods for which you have defined behaviors have been called.

dTell the mock to return "SELECT..." when the getParameter method is called with the "command" string as parameter.

eTell the mock request to return null when getParameter is called with a string parameter passed to it.

9.3.2Finishing the DynaMock tests

Let’s finish transforming the other tests from listing 9.1 into DynaMock tests. Listing 9.10 shows the results.

Listing 9.10 Tests for callView and doGet with dynamic mocks

package junitbook.servlets;

[...]

public class TestAdminServletMO extends TestCase

{

[...]

private Mock mockResponse;

private HttpServletResponse response;

b

Testing servlets with mock objects

207

 

 

protected void setUp()

{

servlet = new AdminServlet()

{

public Collection executeCommand(String command) throws Exception

{

return createCommandResult();

}

};

[...]

 

 

mockResponse = new Mock(HttpServletResponse.class);

 

c

 

response = (HttpServletResponse) mockResponse.proxy();

 

 

}

[...]

private Collection createCommandResult() throws Exception

{

// Same as in listing 9.5

}

public void testCallView() throws Exception

{

servlet.callView(request);

}

public void testDoGet() throws Exception

{

mockRequest.expectAndReturn("getParameter", "command", "SELECT...");

//Verify that the result of executing the command has been

//stored in the HTTP request as an attribute that will be

//passed to the JSP page. mockRequest.expect("setAttribute", C.args(C.eq("result"),

C.isA(Collection.class)));

servlet.doGet(request, response);

}

}

c

c

b You need a new mock for the HttpServletResponse class (used in doGet).

cSet the behaviors of the mock HttpServletRequest object. You also tell DynaMock to verify that the methods are called and that the parameters they are passed

match what is expected. For example, you verify that the setAttribute method call is passed a first parameter matching the "result" string and that the second parameter is a Collection object.

You now have a fully working test suite using mock objects that exercises your servlet code.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]