25.2. Values of MoneyWe will now look in detail at how values of Money can be used in Fit tables. In the process, we will show how the fixture needs to deal with the conversion and comparison issues as discussed in the previous section. Specifically, we need to specify how String values will be converted to objects of that type, and vice versa, and how two values of that type will be checked to see whether they are equal. Consider the altered discount tests shown in Figure 25.1. Here, we require that the money values be shown with a leading $ and exactly two decimal places of precision.
The fixture code for this is the class TestDiscount, as shown in Listing 25.1. The public instance variable amount is of type Money, which Fit does not handle automatically. To handle conversion from the textual form of the value to a corresponding objecthere, of Moneythe fixture defines the method parse(). This method overrides the default method in class Fixture to specify how to convert a textual value, from a table cell, into an object of the right class. This method is called whenever a TypeAdapter is needed by a fixture, such as when a ColumnFixture is processing the labels in the header of the table. The parse() method in class TestDiscount, as shown in Listing 25.1, checks whether the type is Money. If so, the method calls the static method parse() of class Money. Otherwise, the superclass method is called to handle it. Listing 25.1. TestDiscount.javapublic class TestDiscount extends fit.ColumnFixture { public Money amount; private Discount application = new Discount(); public Money discount() { return application.discount(amount); } public Object parse(String s, Class type) throws Exception { if (type == Money.class) return Money.parse(s); return super.parse(s, type); } } As Fit needs to report unexpected values, a String value from our Money object is needed. The standard method toString(), as defined in class Object, is used for this purpose. As Fit fixtures need to make comparisons, we need a way to test whether the expected and actual values, or objects, are the same. Fit relies on the standard method equals() to do this. The relevant part of our application class Money is shown in Listing 25.2. The static method parse() takes a String and converts it to an object of Money. The method toString() provides a String value. The equals() method checks whether two Money objects are the same; it is called by Fit with the expected and actual values after they have been converted to objects. Listing 25.2. Money.javapublic class Money { private long cents; public Money(long cents) { this.cents = cents; } public boolean equals(Object other) { return other instanceof Money && ((Money)other).cents == cents; } public int hashCode() { return (int)cents; } public String toString() { String centString = ""+cents%100; if (centString.length() == 1) centString += "0"; return "$"+cents/100+"."+centString; } public static Money parse(String s) { if (s.charAt(0) != "$") throw new RuntimeException("Invalid money"); int dot = s.indexOf("."); if (dot < 0 || dot != s.length() - 3) throw new RuntimeException("Invalid money"); String scent = s.substring(1); double amount = Double.valueOf(scent).doubleValue()*100; return new Money((long)amount); } // ... } Questions & Answers
|