Testing lists of objects is usually a pain, but FitNesse makes it very easy.
So far, we have always been testing a predefined
number of items or steps. Now we'll learn how to verify a bunch of
objects at once using ArrayFixture and RowFixture.
In this chapter, we'll implement the following user story:
View tickets
As a player, I want to view my tickets, so that I can find out if I have won and how much.
The customers tell us that a player should be able to view all his open tickets (tickets for open draws) and all his tickets for any particular draw. For open draws, we need to show selected numbers, ticket value and draw date. When the player views tickets by draw, we should display selected numbers, ticket value and winnings.
Our job is done when the following test cases run correctly:
A draw on 01/01/2008 is open, and player John has 100 dollars in his account. He buys a single ticket for numbers 1, 3, 4, 5, 8, 10; another single ticket for 2, 4, 5, 8, 10, 12; and five tickets for numbers 3, 6, 9, 12, 15, 18. When he views his open tickets, he should see three tickets for the draw on 01/01/2008, with 10 dollars on the first two sets of numbers and 50 dollars on the third set of numbers.
Two players have tickets in the same draw. Tom buys a ticket with numbers 2, 4, 5, 8, 10, 12 for the draw on 01/01/2008. John buys a ticket with numbers 1, 3, 4, 5, 8, 10 for the same draw. When Tom views tickets for the draw on 01/01, he should see only his ticket, not John’s. Likewise for John.
Draws on 01/01, 02/01 and 03/01 are open. Player John has 100 dollars in his account. He buys a ticket with the numbers 1, 3, 4, 5, 8,10 for the draws on 01/01 and 02/01, and five tickets with numbers 3, 6, 9, 12, 15, 18 for the draw on 01/01. When he views his tickets for the draw on 01/01, he should see 10 dollars on 1, 3, 4, 5 ,8, 10 and 50 dollars on 3, 6, 9, 12, 15, 18. For the draw on 02/01, he should see just 10 dollars on 1, 3, 4, 5, 8, 10. All tickets are open. For the draw on 03/01, he should see no tickets.
Continuing the third test, numbers 1, 3, 4, 5, 31, 32 are drawn on 01/01/2008, and John has a winning ticket with four correct numbers. Now, when he lists tickets for the draw on 01/01, he should see that both tickets are closed, and that the 10-dollar ticket has three dollars of associated winnings (the total pool was 60 dollars, the payout pool was 30 dollars, and the 4-out-of-6 prize is 10% of this). When John lists his open tickets, he should only see the ticket for 02/01.
These test scripts give us some new ideas about the problem domain. As we learned in the previous chapter, tickets can have different values. But in this case, our clients want five tickets for 10 dollars on the same set of numbers and for the same draw to appear as one 50-dollar ticket. The test scripts also call for a new kind of test: checking the contents of a list of objects (tickets a player has in a draw).
All four tests for this chapter use a draw on 01/01 and a player called John. So let's start the test, open the draw and create this player in a common setup page:
1 !|Tristan.Test.ReviewTickets| 2 3 |Draw on |01/01/2008| is open| 4 5 |Player | john | opens account with | 100 | dollars|
The first test should look like this:
TicketReviewTests.SeveralTicketsOneDraw
1 |Player|john|buys a ticket with numbers|1,3,4,5,8,10|for draw on|01/01/2008| 2 3 |Player|john|buys a ticket with numbers|2,4,5,8,10,12|for draw on|01/01/2008| 4 5 |Player|john|buys|5|tickets with numbers|3,6,9,12,15,18|for draw on|01/01/2008| 6 7 |Player|john|lists open tickets| 8 |draw|numbers|value| 9 |01/01/2008|1,3,4,5,8,10|10| 10 |01/01/2008|2,4,5,8,10,12|10| 11 |01/01/2008|3,6,9,12,15,18|50|
To implement this test, we need to find open tickets of a particular player. Let's add
a method for this to
DrawManager:
22 ListGetOpenTickets(int playerId);
Everything except the last table in the test looks very
similar to methods and tables from the previous two
chapters. The last table presents us with a new problem,
because we need to check a list of elements. In
Embed fixtures for best results
we used a ColumnFixture to check several accounts at
once, but the situation here is a bit different. This test can
return more or less rows than expected.
Implementing this test with ColumnFixture would be
relatively tricky. We would need separate checks for collection
size and collection contents. In the
collection contents test, we would have to create a wrapper
to fetch an element by some key property (assuming
that there is a key property), and then test
other properties. DoFixture has a very useful shortcut for
tests like these: it just returns the whole list.
See the method
PlayerListsOpenTickets
below.
9 public class ReviewTickets:fitlibrary.DoFixture
10 {
11 private IDrawManager _drawManager;
12 private IPlayerManager _playerManager;
13 public ReviewTickets()
14 {
15 _playerManager = new PlayerManager();
16 _drawManager = new DrawManager(_playerManager);
17 }
18 public void DrawOnIsOpen(DateTime drawDate)
19 {
20 _drawManager.CreateDraw(drawDate);
21 }
22 public void PlayerOpensAccountWithDollars(String player, decimal balance)
23 {
24 PlayerRegistrationInfo p = new PlayerRegistrationInfo();
25 p.Username = player; p.Name = player;
26 p.Password = "XXXXXX";
27 // define other mandatory properties
28 int playerId = _playerManager.RegisterPlayer(p);
29 _playerManager.AdjustBalance(playerId, balance);
30 }
31 public void PlayerBuysATicketWithNumbersForDrawOn(
32 string username, int[] numbers, DateTime date)
33 {
34 PlayerBuysTicketsWithNumbersForDrawOn(username, 1, numbers, date);
35 }
36
37 public void PlayerBuysTicketsWithNumbersForDrawOn(
38 string username, int tickets, int[] numbers, DateTime date)
39 {
40 int pid = _playerManager.GetPlayer(username).PlayerId;
41 _drawManager.PurchaseTicket(date, pid, numbers, 10 * tickets);
42 }
43 public IList PlayerListsOpenTickets(String player)
44 {
45 return _drawManager.GetOpenTickets(
46 _playerManager.GetPlayer(player).PlayerId);
47 }
58 }
If a DoFixture method returns an array or an
IEnumerable
collection, the result is automatically wrapped into an
ArrayFixture
for testing.
ArrayFixture is a FitLibrary class
for testing arrays and collections. It can check
contents of an array and verify that there are no additional or
missing elements. The second row of an
ArrayFixture table lists
element properties,[22]
and all the following rows contain the expected contents of the array.
Properties not included in the table are just ignored when comparing
actual results with expected results, so you
can hide unimportant details. ArrayFixture
compares the array or collection with the table by checking
all the given properties, in the order of the elements listed in
the table. It reports any elements out of order,
elements that were not in the
test method result (marked as
missing), and elements returned by the test method that were not expected
in the table (marked as surplus).
The first test is now complete (Figure 9.1, “DoFixture
automatically wraps arrays and
IEnumerable
collections into
ArrayFixture,
allowing us to easily verify their contents.
”).
Now that we know how to test lists of objects, we can
easily write the second and third test cases for this chapter.
Let’s check for the tickets using the table header
“Player
XXX
lists tickets for draw on
YYY”.
The second test looks like this:
TicketReviewTests.TwoAccountsOneDraw
1 |Player|tom|opens account with|50|dollars| 2 3 |Player|john|buys a ticket with numbers|1,3,4,5,8,10|for draw on|01/01/2008| 4 5 |Player|tom|buys a ticket with numbers|2,4,5,8,10,12|for draw on|01/01/2008| 6 7 |Player|john|lists tickets for draw on|01/01/2008| 8 |value|numbers| 9 |10|1,3,4,5,8,10| 10 11 |Player|tom|lists tickets for draw on|01/01/2008| 12 |value|numbers| 13 |10|2,4,5,8,10,12|
To implement it, we’ll need a method in the main test fixture that returns a list of tickets in a draw for a player:
48 public IListPlayerListsTicketsForDrawOn( 49 String player, DateTime date) 50 { 51 return _drawManager.GetTickets( 52 date,_playerManager.GetPlayer(player).PlayerId); 53 }
And a corresponding method in DrawManager:
23 ListGetTickets(DateTime drawDate, int playerId);
Figure 9.1. DoFixture automatically wraps arrays and IEnumerable collections into ArrayFixture, allowing us to easily verify their contents.

![]() | Stuff to remember |
|---|---|
|

![[Tip]](../images/resources/tip.png)
![[Note]](../images/resources/note.png)


