Method seems to work ok but the test fails - why?

Can anyone help me by explaining why this test fails?

An article has a title and a url (among other things). If we don’t get
a title from the create article form, then i use hpricot and open-uri to
look on the net and generate the title from the web page’s title. In
the context of my app, it works fine (although the code is quite clumsy,
i’m still a noob coder). However, a simple test that the article has a
title is failing - in the tests, the constructor doesn’t seem to be
doing its job properly.

here’s the test:

#article should generate a title from a url if not given a title
def test_makes_a_title_from_url
article_hash = {:url => “www.google.co.uk”}
article = Article.new(:article => article_hash, :user => 1)
assert_equal(“iGoogle”, article.title)
end

The test is failing because title is equal to nil. (normally i would
just assert_not_nil, but i used assert_equals here because i wanted the
test to output what title was equal to, in case it was some broken
string or something)

Here’s the constructor:

##################################################################
#constructor - takes the data from the article form (the
#article/new view page), as a hash called :article, and the
#current user, as :user
##################################################################
#params:

- :article - a hash containing :url, :title, :tags

- :user - a user, usually the current user (the person creating

#the article)
##################################################################
def initialize(params = {})
super(params[:article])
#first, check that the url is a valid web page
begin
web_page = open(self.url)
rescue #look for any exceptions
#if it failed to validate the url, delete the object and return
self.destroy
return
end
#autogenerate the title from the web page’s title element if a
#title is not given
if self.title == “”
self.title = ((Hpricot(web_page))/“title”).first.inner_html
end
#set some other values
self.added_at = DateTime.now.to_s
self.points = 0
self.user_id = params[:user]
self.save
#mark as scored up by the user who added it
self.change_score :user_id => self.user_id, :points => 1
return true
end

I thought it might be to do with hpricot/open-uri so i required them at
the top of the test. But that hasn’t helped - i don’t even know if
that’s the proper way to handle requires in testing. (Will the tests
automatically use the requires and includes in my environment.rb? I
don’t have anything in environment/test.rb besides the default stuff
rails puts in there.)

This is probably something dumb, and obvious to most - can anyone see
what i’m doing wrong?

Hi,

I’ve never used hpricot, so I thought I’d give this a try in irb. If I
do

doc = Hpricot(open(“www.google.co.uk”))

I get an error: “No such file or directory - www.google.co.uk

However, if I prepend “http://” to the url

doc = Hpricot(open(“http://www.google.co.uk”))

it works. So, give that a try and let everyone know if that works.

I’d also like to offer this idea re: your Article constructor: it does
too
much. Fetching the title of a web page has nothing to do with an
Article.
Rather, an Article constructor should simply ensure that it is given a
non-nil title, i.e., Article validates the presence of its title.
Therefore,
consider extracting a class whose purpose it is to build Articles, and
give
it the responsibility of using a given title or fetching one from the
url to
build an Article. Doing so will allow you to test Article in isolation
from
fetching a title from a url, resulting in shorter, more focused tests.
Furthermore, separating these concerns will move your classes closer to
having a single
responsibilityhttp://en.wikipedia.org/wiki/Single_responsibility_principle[
Single-responsibility principle - Wikipedia], a design
for
which to strive.

Regards,
Craig

Craig D. wrote:

Hi,

doc = Hpricot(open(“www.google.co.uk”))

I get an error: “No such file or directory - www.google.co.uk

However, if I prepend “http://” to the url

doc = Hpricot(open(“http://www.google.co.uk”))

it works. So, give that a try and let everyone know if that works.

Thanks craig - i spotted that as a potential problem and fixed it but
the test still fails in the same way.

Rather, an Article constructor should simply ensure that it is given a
non-nil title, i.e., Article validates the presence of its title.

I’m not very happy with my constructors generally. Ideally i’d like to
do more research and then rewrite my app according to cleaner
principles. I just dove in and started doing stuff, learning as i went
along. I have learnt a lot, but i know now that most of my code is
pretty clunky. (i’m a newcomer to programming and rails in particular).

Thanks for the advice :slight_smile:

max

Craig D. wrote:

If you can make your project available via anonymous checkout or some
kind
of download, I and/or someone else could try it and maybe offer a
solution.
Barring that, post as much code as you can, say your whole test and your
whole Article class.

Doing is one of the best ways to learn, and you have a great community
willing to help when you get stuck. :slight_smile:

max

Appreciate that Craig :slight_smile:

I’m going to have a rethink about a few things before posting my class
up, so i’ll leave it for now. Thanks for all your help though.

On 9/22/07, Max W. [email protected] wrote:

However, if I prepend “http://” to the url

doc = Hpricot(open(“http://www.google.co.uk”))

it works. So, give that a try and let everyone know if that works.

Thanks craig - i spotted that as a potential problem and fixed it but
the test still fails in the same way.

If you can make your project available via anonymous checkout or some
kind
of download, I and/or someone else could try it and maybe offer a
solution.
Barring that, post as much code as you can, say your whole test and your
whole Article class.

Rather, an Article constructor should simply ensure that it is given a

non-nil title, i.e., Article validates the presence of its title.

I’m not very happy with my constructors generally. Ideally i’d like to
do more research and then rewrite my app according to cleaner
principles. I just dove in and started doing stuff, learning as i went
along. I have learnt a lot, but i know now that most of my code is
pretty clunky. (i’m a newcomer to programming and rails in particular).

Thanks for the advice :slight_smile:

Doing is one of the best ways to learn, and you have a great community
willing to help when you get stuck. :slight_smile:

max