Mock Objects Revisited


In Lesson 10, you created a mock class to force the behavior of a random number generator. The mock class you built extended from the class java.util.Random. You built the mock class as a nested class within the test. Since the mock class was used solely by the test, it was beneficial to include the mock code directly within the test class. In this lesson, you'll learn an even more succinct technique: embedding the mock class completely within a test method.

You might need to use mock objects if your code must interact with an external API. You typically have little control over the external code or the results an API returns. Writing tests against such code often results in breakage due to changing results from the API. Also, the API might communicate with an external resource that is not always available. Such an API introduces a bad dependency that mocks can help you manage.[1]

[1] [Langr2003].

Ensure that you have a dependency issue before introducing mocks.


The student Account class needs to be able to handle transfers from an associated bank account. To do so, it must interact with ACH (automated clearing house) software from Jim Bob's ACH Shop. The ACH software publishes an API specification. Another bad dependency: We haven't licensed or installed the actual software yet! But you need to start coding now in order to be able to ship working software soon after the actual code is licensed and delivered.


The test itself is small.

 package sis.studentinfo; import java.math.BigDecimal; import junit.framework.*; public class AccountTest extends TestCase {    static final String ABA = "102000012";    static final String ACCOUNT_NUMBER = "194431518811";    private Account account;    protected void setUp() {       account = new Account();       account.setBankAba(ABA);       account.setBankAccountNumber(ACCOUNT_NUMBER);       account.setBankAccountType(Account.BankAccountType.CHECKING);    }    // ...    public void testTransferFromBank() {       account.setAch(new com.jimbob.ach.JimBobAch()); // uh-oh       final BigDecimal amount = new BigDecimal("50.00");       account.transferFromBank(amount);       assertEquals(amount, account.getBalance());    } } 

Debiting an account requires the bank's ABA (routing) number, the account number, and the type of account. You can populate this required account information using the setUp method.


The test method, testTransferFromBank, creates a new JimBobAch object and passes it into the Account object. Uh-oh; you don't have the JimBobAch class yet, so the code won't even compile. You'll solve this problem shortly with a mock class.

The remainder of the test sends the TRansferFromBank message to the account, then asserts that the account balance increased to the correct amount.

So how will you solve the problem of the nonexistent JimBobAch class? You do have just about everything else you need. Jim Bob ACH Company has supplied you with the API documentation.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net