...
That class follows the general rules of fixtures described in the Fixture Conventions Developer Guide (Under Construction). It exposes the instance variable dividend to map with the given column dividend. The given column divisor corresponds to the public instance variable divisor. The expected column quotient? is mapped to the public instance method quotient().
...
Writing fixtures for List of Value
As we've seen in the Collection Interpreters, the collection interpreters are used to express a collection of data to be compared with the system under development.
...
This page shows the fixture code that supports the examples introduced in the definition.
Using the CollectionInterpreter alone
...
That class follows the general rules of fixtures described in Fixture Conventions Developer Guide (Under Construction). It provides public instance methods openCheckingAccount and thatBalanceOfAccount to map respectively to the actions open checking account and that balance of account.
Info |
---|
The fixture does not much except from delegating the processing to the application code, in this case the Bank class. |
Code Block | ||||
---|---|---|---|---|
| ||||
public class Bank {
private final HashMap<String, BankAccount> accounts;
public Bank()
{
accounts = new HashMap<String, BankAccount>();
}
public boolean hasAccount(String accountNumber)
{
return accounts.containsKey(accountNumber);
}
public BankAccount getAccount(String accountNumber) throws NoSuchAccountException
{
if (!hasAccount(accountNumber)
throw new NoSuchAccountException(accountNumber);
return accounts.get(accountNumber);
}
public CheckingAccount openCheckingAccount(String number, Owner owner)
{
if (hasAccount(number)) return null;
CheckingAccount account = new CheckingAccount(number, owner);
accounts.put(number, account);
return account;
}
} |
How is the example interpreted?
When it runs this example, reads the first table to decide on the interpreter and fixture to use and start testing from the second table, which is the first test table.
The second table is a default action, which carries out in the following sequence of steps:
- It calls the method openCheckingAccountUnderTheNameOf() with the parameters 12345-67890, Spongebob and Squarepants
- Since the method returns true, indicating a success, it marks the keyword cells as right, resulting in the first cell of the row being colored green.
The third table is a check action, which carries out in the following sequence of steps:
- It calls the method thatBalanceOfAccountIs() with the parameter 12345-67890 to get the value calculated by the system under test
- This is a check action, so it reads the value $0.00 from the last cell of the row and compares it to the value returned by the fixture. Since the values are equal, it annotates the last cell as right, which results in the cell being colored green.
What happens for other return types?
Default Rows
Depending on the value returned by the system under test, default actions will annotate keyword cells following these rules:
- If the value is true, it annotates keyword cells right, making them appear green.
- If the value is false - indicating a failure - it annotates keyword cells wrong, making them appear red.
- If the action throws an exception, it annotates the first keyword as an exception, making it appear yellow and display a stack trace of the error.
- If the action returns another value or nothing, it ignores the result.
Check Rows
Depending on the value returned by the system under test, check actions will annotate the row following these rules:
- If the returned value matches the expected value, it annotates the last cell right, making it appear green.
- If the action returns nothing or a value that does not match the expected value - indicating a failure - it annotates the last cell wrong, making it appear red.
- If the action throws an exception, it annotates the first keyword as an exception, making it appear yellow and display a stack trace of the error.
Building on the Bank example
The second example in Writing a Do With specification(link to-do), shown again below, presents a more complete business flow using the bank fixture.
do with | bank |
open checking account | 12345-67890 | under the name of | Spongebob | Squarepants |
check | that balance of account | 12345-67890 | is | $0.00 |
deposit | $100.00 | in account | 12345-67890 | |
check | that balance of account | 12345-67890 | is | $100.00 |
withdraw | $50.00 | from account | 12345-67890 | |
check | that balance of account | 12345-67890 | is | $50.00 |
reject | withdraw | $75.00 | from account | 12345-67890 |
check | that balance of account | 12345-67890 | is | $50.00 |
accept | withdraw | $25.00 | from account | 12345-67890 |
end |
The fourth and last example table also contains several rows. In a sequence of actions, all of the rows in a table are executed, so several actions can be grouped in a table if that helps improve clarity.
In the first row of the last table, notice the use of the reject special keyword in the first cell. This indicates that the action for the row is expected to fail by either returning false or throwing an exception.
In the last row of the last table, the accept special keyword is used to indicate that we expect the last call to succeed. Accept is the opposite of reject. That is, the last withdraw should not return false nor throw an exception.
Reject Rows
Depending on the value returned by the system under test, reject actions will annotate the row following these rules:
- If the action returns false or throws an exception - indicating a success - it annotates the reject keyword right, making it appear green.
- If the returned value is anything else or nothing - indicating a failure - , it annotates the reject keyword wrong, making it appear red.
Accept Rows
Depending on the value returned by the system under test, accept actions will annotate the row following these rules:
- If the returned value is anything except false or an exception - indicating a success -, it annotates the accept keyword right, making it appear green.
- If the action returns false or throws an exception - indicating a failure - it annotates the accept keyword wrong, making it appear red.
Show me the code
The supporting code is here:
Code Block | ||||
---|---|---|---|---|
| ||||
public class BankFixture
{
private Bank bank;
public BankFixture()
{
bank = new Bank();
}
public boolean openCheckingAccountUnderTheNameOf(String number, String firstName, String lastName)
{
return bank.openCheckingAccount(number, new Owner(firstName, lastName)) != null;
}
public Money thatBalanceOfAccountIs(String accountNumber) throws Exception
{
BankAccount account = bank.getAccount(accountNumber);
return account.getBalance();
}
public void depositInAccount(Money amount, String accountNumber) throws Exception
{
bank.deposit(amount, accountNumber);
}
public boolean withdrawFromAccount(Money amount, String accountNumber) throws Exception
{
return withdrawFromAccountUsing( amount, accountNumber, WithdrawType.ATM );
}
public boolean withdrawFromAccountUsing(Money amount, String accountNumber, WithdrawType withdrawType) throws Exception
{
try
{
bank.withdraw(amount, accountNumber, withdrawType);
}
catch (Exception e)
{
return false;
}
return true;
}
public Collection getOpenedAccounts()
{
return bank.getAccounts();
}
} |
Combining with other types of rules
An interesting characteristic of the DoWithInterpreter is the ability to delegate processing of part of the table to another interpreter.
If an interpreter is specified in the first cell of a row, the remainder of the table will be processed by that interpreter. The action for the row must return a fixture that will be used to interpret the rest of the table.
In the example show below, the first row of the second table indicates to process the rest of the table using a SetOfInterpreter on the value returned by the action opened accounts.
do with | bank |
open checking account | 12345-67890 | under the name of | Spongebob | Squarepants | |
open savings account | 54321-09876 | under the name of | Patrick | Star |
set of | opened accounts | |
number | type | owner name |
12345-67890 | checking | Spongebob Squarepants |
54321-09876 | savings | Patrick Star |
end |
Workflow validation (Scenario)
...