01.02.2013 Views

Software Development Cross Solution - Index of - Free

Software Development Cross Solution - Index of - Free

Software Development Cross Solution - Index of - Free

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

why mock objects?<br />

Q: These mock objects don’t seem to be doing anything I<br />

couldn’t do myself. What are they buying me again?<br />

A: Mock objects give you a way to create custom implementations<br />

<strong>of</strong> interfaces without needing to actually write the code. Just look<br />

at page 303. We needed three different variations <strong>of</strong> gift cards (if<br />

you count the testInvalidGiftCard one). Two <strong>of</strong> them had different<br />

behavior, not just different values. Without the mock objects we’d<br />

have to implement that code ourselves. You could do it, but why?<br />

Q: Why didn’t we use mock objects for the gift cards<br />

themselves?<br />

A: Well, two reasons. First, we’d have to introduce an interface<br />

for the gift cards. Since we don’t have any behavioral variations it<br />

really doesn’t make a lot <strong>of</strong> sense to put an interface here. Second,<br />

all we’re really changing are the values it returns since it’s pretty<br />

much a simple data object anyway. We can get that same result by<br />

just instantiating a couple different gift cards at the beginning <strong>of</strong> our<br />

test and set them to have the values we want. Mock objects (and the<br />

required interface) would be overkill here.<br />

Q: Speaking <strong>of</strong> interfaces, doesn’t this mean I’ll need an<br />

interface at any point I’d want a mock object in my tests?<br />

A: Yes—and truthfully sometimes you end up putting interfaces<br />

in places that you really don’t ever intend on having more than one<br />

implementation. It’s not ideal, but as long as you’re aware that you’re<br />

adding the interface strictly for testing it’s not usually a big deal.<br />

Generally the value you get from being able to unit-test effectively<br />

with less test code makes it worth the trade-<strong>of</strong>f.<br />

Q: What’s that replay(...) method all about?<br />

A: That’s how you tell the mock object that you’re done telling it<br />

what’s about to happen. Once you call replay on the mock object it<br />

will verify any method calls it gets after that. If it gets calls it wasn’t<br />

expecting, in a different order, or with different arguments, it will throw<br />

an exception (and thereby fail your test).<br />

308 Chapter 8<br />

Download at WoweBook.Com<br />

Q: What about arguments...you say they’re compared with<br />

Java’s equals( ) method?<br />

A: Right—EasyMock tests the arguments the mock object gets<br />

during execution against the ones you said it should get by using<br />

the equals() method. This means you need to provide an<br />

equals() method on classes you use for arguments to methods.<br />

There are other comparison operators to help you deal with things<br />

like arrays where the reference value is actually compared. Check<br />

out the EasyMock docs (www.easymock.org/Documentation) for<br />

more details.<br />

Q: So we changed our design a pretty good bit to get all this<br />

testing stuff going. The design feels.. upside-down. We’re telling<br />

the OrderProcessor how to talk to the database now...<br />

A: Yes, we are. This pattern is called dependency injection, and<br />

it shows up in a lot <strong>of</strong> frameworks. Specifically the Spring Framework<br />

is built on the concepts <strong>of</strong> dependency injection and inversion <strong>of</strong><br />

control. In general, dependency injection really supports testing—<br />

particularly in cases where you need to hide something ugly like a<br />

database or the network. It’s all about dependency management and<br />

limiting how much <strong>of</strong> the system you need to be concerned about for<br />

any given test.<br />

Q:So do you need dependency injection to do good testing<br />

or mock objects?<br />

A: No. You could do a lot <strong>of</strong> what we did with the DBAccessor<br />

by using a factory pattern that can create different kinds <strong>of</strong><br />

DBAccessors. However, some people feel that dependency<br />

injection just feels cleaner. It does have an impact on your design,<br />

and it does <strong>of</strong>ten mean adding an interface where you might not have<br />

put one before, but those typically aren’t the parts <strong>of</strong> your design<br />

that cause problems; it’s usually that part <strong>of</strong> the code that no one<br />

bothered to look at because time was getting tight and the project<br />

had to ship.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!