[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Testing a user application

Vincent Foley

5/10/2005 5:46:00 AM

Hi everyone,

I recently wrote a small user application called RJournal[1], and for
the next release I would love to have much more unit tests than I
currently do. However, my problem is that most methods I would like to
test have side effects. For example, I have a method called
LiveJournalClient#post which, as its name says, posts a new message to
LiveJournal. How can I test that this worked without filling up a
journal? Similarily, when the application starts, it checks to see if
the config file exists; if it does not, it should create it and add the
parameters to it: how can I test this if the file already exists? And
without nuking everything I already have.

Ryan Levengood suggested in another thread that I use mock objects for
my testing purposes, but I don't understand clearly how they work.

If anyone could actually write a test or two for my application, so
that I can see how to do it, I would be very grateful.

Vincent.

[1] RJournal: http://ljrb.rub...

4 Answers

Luke Graham

5/10/2005 6:00:00 AM

0

On 5/10/05, Vincent Foley <vfoley@gmail.com> wrote:
> Hi everyone,
>
> I recently wrote a small user application called RJournal[1], and for
> the next release I would love to have much more unit tests than I
> currently do. However, my problem is that most methods I would like to
> test have side effects. For example, I have a method called
> LiveJournalClient#post which, as its name says, posts a new message to
> LiveJournal. How can I test that this worked without filling up a
> journal?

Depending on how your method actually posts messages, you could write
stubs for calls it makes and test them for validity. It would be better to
create a throw-away journal to post to, though. Im guessing these journals
are somewhere online?

> Similarily, when the application starts, it checks to see if
> the config file exists; if it does not, it should create it and add the
> parameters to it: how can I test this if the file already exists? And
> without nuking everything I already have.

If you use unix, you can chroot before starting your app, and then it
will be safe to use absolute pathnames to find/create your config file.
Otherwise, you could add an option that lets you specify the
location of the file for testing purposes.

> Ryan Levengood suggested in another thread that I use mock objects for
> my testing purposes, but I don't understand clearly how they work.

Mock objects are simply objects with the same api as the real object, but
which output some kind of message or log file as to what is happening to them
instead of doing real work.

> If anyone could actually write a test or two for my application, so
> that I can see how to do it, I would be very grateful.

It might be worth doing it yourself just to get a feel for what has to be done.
Im sure theres a million test frameworks written in Ruby already.

--
spooq



James Gray

5/10/2005 2:29:00 PM

0

On May 10, 2005, at 12:49 AM, Vincent Foley wrote:

> Ryan Levengood suggested in another thread that I use mock objects for
> my testing purposes, but I don't understand clearly how they work.

Basically the idea here is that you would make a MockClient object
that supports the same methods as your actual client. However,
instead of sending things to LJ, it could write them to a file for
you to examine or something similar. Then you could use that object
in your tests. Obviously, this wouldn't test the XML-RPC side of
your code and in your case, that's a lot of your functionality at
this point.

For that reason, I really like the idea suggested by Luke of opening
a test blog. I think it's the way to go.

James Edward Gray II



Vincent Foley

5/10/2005 3:03:00 PM

0

Yeah, that's what I'm using right now, I have a blog called
http://www.livejournal.com/... where I post a lot of crap. And
I'm still trying to figure out a way to test the whole YAML file thing,

Ryan Leavengood

5/10/2005 11:17:00 PM

0

Vincent Foley wrote:
>
> Ryan Levengood suggested in another thread that I use mock objects for
> my testing purposes, but I don't understand clearly how they work.

I'm back with your example. To use this, change the initialize for
LiveJournalClient to this:

def initialize(username, hpassword, &block)
@username, @password = username, hpassword
if block
@server = block.call
else
@server = XMLRPC::Client.new("www.livejournal.com",
"/interface/xmlrpc", 80)
end
end

Here is the new test_ljclient.rb:

require "lib/ljclient"
require "test/unit"
require "digest/md5"

class MockServer
attr_reader :method, :hash
def initialize
@exception = nil
end

def call(method, hash={})
@method = method
@hash = hash
if @exception
raise @exception.new('test', 'test')
end
end

def do_raise(exception)
@exception = exception
end
end

class TestLiveJournalClient < Test::Unit::TestCase
def initialize(name)
super(name)
@username = "test"
@password = Digest::MD5.hexdigest("test")
@client = create_client(@username, @password)
end

def create_client(username, password)
LiveJournalClient.new(username, password) do
@server = MockServer.new
end
end

def test_login
assert_nothing_raised(Exception) { @client.login }
assert_equal('LJ.XMLRPC.login', @server.method)
assert_equal(@username, @server.hash[:username])
assert_equal(@password, @server.hash[:hpassword])

bad_login = create_client("aosidoasndoiashd908h12", "")
@server.do_raise(XMLRPC::FaultException)
# Really this XMLRPC exception should be mapped to another
# exception, like RJournal::InvalidLoginException
assert_raise(XMLRPC::FaultException) { bad_login.login }

bad_password = create_client(@username, "")
@server.do_raise(XMLRPC::FaultException)
# Same here, except it should be RJournal::InvalidPasswordException
assert_raise(XMLRPC::FaultException) { bad_password.login }
end

def test_post
subject = 'This is a subject'
event = 'This is an event'
assert_nothing_raised { @client.post(subject, event) }
assert_equal('LJ.XMLRPC.postevent', @server.method)
assert_equal(@username, @server.hash[:username])
assert_equal(@password, @server.hash[:hpassword])
assert_equal(subject, @server.hash[:subject])
assert_equal(event, @server.hash[:event])
# The other parts of the hash should also be tested
end
end