Assertions on a custom object

2 views
Skip to first unread message

Eric Lefevre-Ardant

unread,
Dec 3, 2010, 9:32:55 AM12/3/10
to narrati...@googlegroups.com
hi everyone,

I'm trying to assert things on a table in an HTML page.

So I'd have a test like this:

Given...
When...
Then.the(quant).expects_that(the_table("ordersTable"), has_content(tableContent));

'the_table()' is an extractor that finds a Table in an HTML page. 'has_content()' checks that this table contains the specified data. All well and good.

I also have another test that wants to check that the table is not there.

Given...
When...
Then.the(quant).expects_that(the_table("ordersTable"), is_not_present());

I have a problem. I cannot get the_table() to return an instance of Table, since it does not exist in the HTML page.
I thought about getting is_not_present() to extract the table itself, but it cannot do that, since it does not have access to the actor's tool.

Alternatives:
  • get the_table() to return the tool instead (along with the name of the table, somehow), and do the extraction in the matchers. Not much in the spirit of Narrative.
  • get the_table() to return null; I don't like it as it is to similar to an error code
  • get the_table() to return a special instance of Table, NullObject-style (ABSENT_TABLE, say). Then is_not_present() checks that the instance is equal to ABSENT_TABLE. What bothers me is that it seems that the extractor is doing the work of the matcher. There is also a dependency from the matcher to the extractor.
The latter option seems the least bad to me.

Other ideas?

Thanks,

Eric

PS: FYI, the existing test (not using Narrative) is using JWebUnit's WebTest, which has a assertTableNotPresent() method

Samir Talwar

unread,
Dec 3, 2010, 9:35:47 AM12/3/10
to narrati...@googlegroups.com
We have a similar extractor/matcher pair that use null as the "not there" state. Not great, I know, but it seems to work. The best alternative I can think of is a C-style union or an equivalent to Haskell's Maybe—a class that has one of two states, success or failure. You could then wrap your HTML table in said class and check for explicit failure.

— Samir.

Eric Lefevre-Ardant

unread,
Dec 3, 2010, 9:56:25 AM12/3/10
to narrati...@googlegroups.com
OK. Wouldn't a NullObject be cleaner, though?

Except if you want to reuse the is_not_present() matcher with other extractor. In this case, testing null seems the best bet.

Samir Talwar

unread,
Dec 3, 2010, 10:01:41 AM12/3/10
to narrati...@googlegroups.com
Just started reading about Null Objects. Sounds like a good solution to me. I don't expect you'll want to re-use the `is_not_present` matcher with other things—I'd personally prefer to write one for each type—but it's obviously down to your preferences and the code in question.

— Samir.

Eric Lefevre-Ardant

unread,
Dec 3, 2010, 10:15:45 AM12/3/10
to narrati...@googlegroups.com
Alright.
That leads us to another question I wanted to ask. See, I also want to check for the presence of different types of things:

Then.the(quant).expects_that(the_link("Back to backtests"), is_not_present());

Then.the(quant).expects_that(the_html_table("transactionTable"), is_not_present());

Do you actually have different is_not_present() methods, with different names (maybe "is_not_present_as_a_table()" and "is_not_present_as_a_link()")? That sounds a bit cumbersome.

On the other hand, I do have separate methods when the implementations are different. For example:

Then.the(quant).expects_that(the_html_table("transactionTable"), is_not_present());

Then.the(quant).expects_that(the_equity_chart(), is_not_displayed());

The is_not_present() check that the table is null, but the is_not_displayed() checks that the number of images is zero. Frankly, I'd rather have a single method. Less ambiguity in usage, and would probably make for smoother reading, too.

Curious to hear your thoughts,

Thanks!

Eric

Samir Talwar

unread,
Dec 3, 2010, 12:07:29 PM12/3/10
to narrati...@googlegroups.com
I'd have two called `not_present` and have them take different parameter types, but yes, they'd do the same thing. (I'd probably wrap it in `is(…)` rather than make that part of the name.) Looking at it from this perspective, a simple wrapper around `is(nullValue())` would suffice for most, but what about when not being present is represented as a state other than null? It would mean you'd have to remember that this matcher doesn't apply in some cases, which would be a little painful. I hate remembering how our codebase works—I'd like it to tell me itself.

— Samir.

Eric Lefevre-Ardant

unread,
Dec 6, 2010, 4:26:44 AM12/6/10
to narrati...@googlegroups.com
so... if I understand correctly, instead of 
Then.the(quant).expects_that(the_link("Back to backtests"), is_not_present());

you would have
Then.the(quant).expects_that(the_page(), is_not_present(a_link_called("Back to backtests")));

TBH, I don't see how it would work, since is_not_present(a_link_called("Back to backtests")) would not have a pointer to the value returned by the_page().

hm... maybe I'm just not understanding completely what you mean. Maybe if you could paste a couple of lines of code?

Thanks,

Eric

Samir Talwar

unread,
Dec 6, 2010, 8:42:01 AM12/6/10
to narrati...@googlegroups.com
I'm going to start including code with every suggestion I make. If I'd done that before, I would have realised that last one didn't make sense. Honestly, after thinking about it some more, I'm becoming more and more a fan of your globally-acceptable `not_present` function.

— Samir.
Reply all
Reply to author
Forward
0 new messages