Test/unit question. Accessing class variables?

Hello.
This is my first attempt in trying to use the ruby library test/
unit. Additionally my programming and ruby skills are still around
the beginner stage.

I have a unix utility which I’ve written in ruby and now that it
actually does some work I want to be able to test it. My first
attempt at a unit test was to check the value of a class variable but
this results in the following error

NameError: uninitialized class variable @@bad_users in FindUsersTest

Here is a class and test which demonstrates what I’m trying to
do.

– start class
class Simple
@@whatisit = “false”

def parse(n)
@@whatisit = true if n =~ /yes/
end
end

— start test
require ‘simple’
require ‘test/unit’

class SimpleTest < Test::Unit::TestCase

def test_parse
v = Simple.new
v.parse(“yes”)

assert @@whatisit
end
end

— run test
./test_simple.rb
Started
E
Finished in 0.003813 seconds.

  1. Error:
    test_parse(SimpleTest):
    NameError: uninitialized class variable @@whatisit in SimpleTest
    ./test_simple.rb:14:in `test_parse’

1 tests, 0 assertions, 0 failures, 1 errors

I then added this method into the simple class above

def return_whatisit
@@whatisit
end

Then in my test created a Simple object (v = Simple.new) and then
called the return_whatisit method (eg: v.return_whatisit). I dont
really want to have to add extra methods to the code to support the
retreival of class variables from within the tests. I dont
understand why I’m not able to access the class variable @@whatisit
from within the test script? Is it possible to extend the Simple
class from within the test file itself?
For example iin the test file I would like to add this method to
the Simple class
def return_whatisit
@@whatisit
end

So if you have any tips on how to best approach this situation I
would appreciate it. I figure if I get a better understanding of
using and writing tests that will influence how I write scripts down
the road.

TIA. G

On Nov 14, 2007, at 5:15 PM, [email protected] wrote:

NameError: uninitialized class variable @@bad_users in FindUsersTest
end
v.parse(“yes”)

def return_whatisit
For example iin the test file I would like to add this method to
the Simple class
def return_whatisit
@@whatisit
end

So if you have any tips on how to best approach this situation I
would appreciate it. I figure if I get a better understanding of
using and writing tests that will influence how I write scripts down
the road.

I don’t know how to solve your problem under the constraints you
impose – that is, with a class variable but without writing some
kind of accessor method. The following quote from the Pickaxe book
suggests there is no support for what you want in Ruby.

Class variables are private to a class and its instances. If you

want to make them acces-
sible to the outside world, you’ll need to write an accessor
method. This method could
be either an instance method or … a class method.

Do you really need to use a class variable?

Regards, Morton

On 15 Nov 2007, at 07:15, [email protected] wrote:

NameError: uninitialized class variable @@bad_users in FindUsersTest
end
v.parse(“yes”)

def return_whatisit
@@whatisit
end

Then in my test created a Simple object (v = Simple.new) and then
called the return_whatisit method (eg: v.return_whatisit). I dont
really want to have to add extra methods to the code to support the
retreival of class variables from within the tests. I dont
understand why I’m not able to access the class variable @@whatisit
from within the test script? Is it possible to extend the Simple
class from within the test file itself?

The class ‘SimpleTest’ has nothing to do with your class ‘Simple’.
They share a name but nothing else so you can’t access the class
variable directly.

TIA. G

The approach you suggest (defining an extra helper method in the test)
seems to work fine though?

[alexg@powerbook]/Users/alexg/Desktop(6): cat simple.rb
class Simple
@@whatisit = “false”

def parse(n)
@@whatisit = true if n =~ /yes/
end
end
[alexg@powerbook]/Users/alexg/Desktop(7): cat test.rb
require ‘simple’
require ‘test/unit’

class Simple
def return_whatisit
@@whatisit
end
end

class SimpleTest < Test::Unit::TestCase

def test_parse
v = Simple.new
v.parse(“yes”)

assert v.return_whatisit

end

end
[alexg@powerbook]/Users/alexg/Desktop(8): ruby test.rb
Loaded suite test
Started
.
Finished in 0.004223 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

Alex G.

Bioinformatics Center
Kyoto University

weathercoach wrote:

This is my first attempt in trying to use the ruby library test/
unit. Additionally my programming and ruby skills are still around
the beginner stage.
I have a unix utility which I’ve written in ruby and now that it
actually does some work I want to be able to test it.

Next time, write the tests at the same time as you write the code. This
is called “Test Driven Development”, and it usually prevents issues like
yours before they have a chance to exist.

Specifically, your objects’ interfaces will remain very narrow and
decoupled. Tests usually sense the program state from convenient return
values, and private variables remain private.