• No se han encontrado resultados

Actualidades: trascender el género normativo

In document Yoania: grupo masculino de reflexión (página 68-71)

1.2 Desarrollo teórico instrumental sobre las posibilidades configurativas de nuevas identidades masculinas desde la perspectiva de género

1.2.3. Actualidades: trascender el género normativo

myTableChangedCalls.verify( );

myTableChangedParameter0Values.verify( );

}

}

The generated code relies on code found in the Mock Objects framework for keeping track of expectations, such as the expected events or number of times a method was called. You use this class almost exactly like you would use the hand-coded mock object, as shown in Example 6-5 (although the method names are slightly different).

Here is how you can run MockMaker from an Ant buildfile:

<path id="classpath.mockmaker">

<pathelement path="${dir.build}"/>

<pathelement

location="${env.MOCKMAKER_HOME}/mockmaker.jar"/>

<pathelement

location="${env.MOCKMAKER_HOME}/mmmockobjects.jar"/>

<pathelement location="${env.MOCKMAKER_HOME}"/>

</path>

...

<target name="generateMockObjects" depends="prepare">

<java fork="true" classname="mockmaker.MockMaker"

output="${dir.generatedSrc}/MockTableModelListener.java">

<classpath refid="classpath.mockmaker"/>

<arg line="javax.swing.event.TableModelListener"/>

</java>

</target>

6.6.4 See Also

Recipe 6.2 and Recipe 6.3 show how to hand-code mock objects that look similar to the code generated by MockMaker. The Mock Objects web site, http://www.mockobjects.com, lists URLs for several other mock object generation tools, including Easy Mock, Mock Creator, and Mock Doclet.

6.7 Breaking Up Methods to Avoid Mock Objects

6.7.1 Problem

You want to test a method without resorting to the complexity of mock objects.

6.7.2 Solution

Split the method into smaller pieces, ensuring that each piece performs one task. Small, single-purpose methods improve code quality in addition to making them testable.

6.7.3 Discussion

Example 6-12 shows a method that is hard to test. It is hard because you must create a mock

ResultSet

implementation in order to write your tests.

Example 6-12. Hard to test

// fetch an account type code from the database and convert it

// into one of the Account constants

int getAccountType(ResultSet rs, String acctTypeColName)

throws SQLException, DataSourceException {

String acctStr = rs.getString(acctTypeColName);

if ("SA".equals(acctStr)) {

return Account.SAVINGS;

}

if ("CH".equals(acctStr)) {

return Account.CHECKING;

}

throw new DataSourceException("Unknown account type: " +

acctStr);

}

The fundamental problem is that this method performs two tasks, rather than one. It is also a little messy because it throws two types of exceptions. The first task is to retrieve data from the

ResultSet

. The second task is to convert that data into some other form.

When confronted with a method like this, do not try to write a sophisticated unit test. Instead, first try to simplify the method. Example 6-13 shows a simplified version of this method. It is now assumed that the caller obtains the account code from the database before calling this method, whose sole purpose is converting that string into a Java constant.

// convert a database account code, such as "CH", into a Java

constant

int getAccountType(String acctTypeStr)

throws DataSourceException {

if ("SA".equals(acctTypeStr)) {

return Account.SAVINGS;

}

if ("CH".equals(acctTypeStr)) {

return Account.CHECKING;

}

throw new DataSourceException("Unknown account type: " +

acctTypeStr);

}

You can now test this method without resorting to mock objects. We also eliminated the extra

SQLException

because we no longer use JDBC in this method. Example 6-14 shows the test.

Example 6-14. Test for the getAccountType( ) method

public void testGetAccountType( ) throws Exception {

AccountFactory acctFact = new AccountFactory( );

assertEquals("account type", Account.CHECKING,

acctFact.getAccountType("CH"));

assertEquals("account type", Account.SAVINGS,

acctFact.getAccountType("SA"));

try {

acctFact.getAccountType("bogus");

fail("Expected DataSourceException");

} catch (DataSourceException expected) {

}

}

6.7.4 See Also

This method was taken from Example 6-8 earlier in this chapter.

6.8 Testing Server-Side Business Logic

6.8.1 Problem

You want to test business logic that normally depends on a database, but mocking out the low-level SQL is far too complex.

6.8.2 Solution

Organize your server-side code using business objects and database access objects (DAOs). Place all business logic in your business objects, and all database access in your DAOs. Use a factory to create mock implementations of your DAOs when testing your business objects.

6.8.3 Discussion

We showed how to write mock objects to simulate low-level SQL code earlier in this chapter. It is a useful technique for testing the data access tier of your application, but tends to be far too complex for business logic tests. For business objects, you should strive to create mock implementations of the entire data access tier, rather than mock implementations of the JDBC interfaces.

Figure 6-1 illustrates a common design pattern for server-side Java code. In this diagram, either an EJB or a servlet dispatches method calls to

CustomerBO

, a business object that contains server- side business logic. The business object is what we would like to test.

Figure 6-1. Business object and DAO pattern

The first box in Figure 6-1 shows either an EJB or a servlet. This pattern works well with either approach, although the EJB approach allows you to easily invoke many different business objects under the umbrella of a single transaction. Regarding testing, the business object pattern is fantastic because you can test

CustomerBO

as you would test any other standalone Java class. That is, you don't need to run your tests inside of the application server.

The second key to making business objects testable is keeping data access code separate. The

CustomerDAO

interface defines an API to a data source, and the

OracleCustomerDAO

is an Oracle-specific implementation. When using this approach, your business objects generally locate the correct DAO implementations using some sort of factory object. Example 6-15 shows what some of the methods in

CustomerDAO

might look like.

Example 6-15. CustomerDAO methods

In document Yoania: grupo masculino de reflexión (página 68-71)