Running minitest produces no output - ruby

I have a file my_test.rb with the following contents:
require 'test/unit'
class MyTest < Test::Unit::TestCase
# Called before every test method runs. Can be used
# to set up fixture information.
def setup
# Do nothing
end
# Called after every test method runs. Can be used to tear
# down fixture information.
def teardown
# Do nothing
end
# Fake test
def dummy_test
print "Something!"
fail
end
end
When I run ruby my_test.rb, there is absolutely no output.
How can I run the unit tests in this file and see whether they are passing or failing?

There's nothing bad with your implementation and your actual code. But in order your dummy_test can execute what's inside its definition, it should be called first; thing you're not doing, that's why when you run your file you don't get any output.
You can create an example test, and there call your dummy_test method:
...
def test_something
dummy_test
end
# Fake test
def dummy_test
print "Something!"
fail
end

Test-unit will look for methods that start with “test” and use them as test methods. Your code has a method that ends with “test” but none that start with it, so it doesn’t see any tests to run.
Change the method name from dummy_test to test_dummy and you should see the output you are expecting.

As said before you are not calling on your function and therefore nothing will happen since ruby does not automatically execute the first / last function.
An example would be to implement this code
...
def main()
print "Something!"
end
main()
And if you would like to call a function which calls the other functions you will do the same
Example:
def main()
other_function1()
other_function2()
end
main()
And the other_functions would be other functions you define and call within the main function.

Related

can common overriding code be shared

I am new to ruby and I'm hoping someone can help me. I am writing tests using test::unit and within my tests I needed to run some code before an assert was called so I overrided the assert methods like so:
class TestSomething < Test::Unit::TestCase
def assert_equal(expected, actual, message = nil)
mycode ..
super(expected, actual, message)
end
def assert(object, message)
my code ...
super(object, message)
end
def assert_not_nil(object, message = "")
my code ...
super(object, message)
end
def setup
end
def test_case1
end
def test_case1
end
def teardown
end
end
The above structure works fine and the asserts call my code. The thing is I have 100s of test classes. The assert overriding will be the same for all of them. Do I have to copy the assert overrides to the top of every class or is there a way for all of them to get the assert overrides in one go?
One more question. Is there a way of catching an error if it occurs anywhere within the entire class?
A
I am not sure why you do not want to use before filter, but the question as it was stated has an answer: since ruby classes are open, one might do the following.
class Test::Unit::TestCase
# store the original
alias_method :assert_equal_original, :assert_equal
# override
def assert_equal *args
# mycode ..
assert_equal_original *args
end
# the same for other methods
end
Once it is done, any derived class will call my_code before calling the original method.
To catch an error within the scope of the class is impossible, AFAIK.

How to call or activate a class?

In my lib folder I have billede.rb:
class Billede
require 'RMagick'
#some code that creates a watermark for a image
image.write(out)
end
How do I call/activate the class? Is the only way to change it to a Rake task?
You can't call a class directly. You have to call a method on that class. For example:
class Billede
def self.foobar
# some kind of code here...
end
end
Then you can call it via Billede.foobar
Perhaps you should read some documentation on basic ruby syntax before trying to do more complex things (such as manipulating images w/ Rmagick).
Code 'inside a class' is run just like any other code. If you have a Ruby file like this:
puts "Hello from #{self}"
class Foo
puts "Hello from #{self}"
end
and you run the file (either via ruby foo.rb on the command line or require "./foo" or load "foo.rb" in a script) it then you will see the output:
Hello from main
Hello from Foo
If you want to load a utility that 'does something' that you can then invoke from a REPL like IRB or the Rails console, then do this:
module MyStuff
def self.do_it
# your code here
end
end
You can require "./mystuff" to load the code, and when you're ready to run it type MyStuff.do_it
And, as you may guess, you can also create methods that accept arguments.
If you want to define a file that can be included in others (with no immediate side effects) but which also "does its thing" whenever the file is run by itself, you can do this:
module MyStuff
def self.run!
# Go
end
end
MyStuff.run! if __FILE__==$0
Now if you require or load this file the run! method won't be invoked, but if you type ruby mystuff.rb from the command line it will.
# in /lib/billede.rb
class Billede
def self.do_something(arg)
# ...
end
def do_anotherthing(arg)
# ...
end
end
# inside a model or controller
require 'billede'
Billede::do_something("arg")
# or
billede_instance = Billede.new
billede_instance.do_anotherthing("arg")

Assert method call without stub?

I would like to assert that a particular method was called, but I don't want to mock/stub the method - I want to include that code in the test as well.
For example, in Ruby, something like:
def bar()
#stuff I want to test
end
def foo()
if condition
bar()
end
#more stuff I want to test
end
# The test:
foo()
assert_called :bar
Does anyone have a suggestion (or a better way to go about it)? My actual code is quite a bit more complex, so please don't take the simplicity of the example into account.
Perhaps something like:
require 'set'
class Class
def instrument
self.instance_methods.each do |m|
old = method(m)
define_method(m) do |*a,&b|
#__called__ ||= Set.new
#__called__ << m
old.bind(self).call(*a,&b)
end
end
end
end
class Object
def assert_called(method)
if not (#__called__ && #__called__.include?(method))
# You will have to figure out how to make this equivalent to a failing
# assertion for your favorite test framework
raise "Assertion failed! #{method} has not been called"
end
end
end
Then after defining your classes, but before running tests:
FooClass.instrument
Note that I haven't tested this code yet!
It's really a good way to make it two test cases, one would call foo() and check if bar() is called and another to check if bar() does it's thing well. When you're testing foo(), you should know what bar() should return.

How to assert block of a mock in mocha

This example is contrived, please don't take it verbatim as my code.
I have the need to assert something like the following:
def mymethod
Dir.chdir('/tmp') do
`ls`
end
end
In the end I want to assert that:
Dir.chdir is invoked with the appropriate parameters.
` is invoked with the appropriate parameters
I started off with...
Dir.expects(:chdir).with('/tmp')
but after that I'm not sure how to invoke the block passed to Dir.chdir.
You need to use the mocha yields method. Also, writing an expectation for the backtick method is rather interesting. You need to make an expectation like this:
expects("`")
But on what object? You might think on Kernel or Object, but that doesn't actually work.
As an example, given this module:
module MyMethod
def self.mymethod
Dir.chdir('/tmp') do
`ls`
end
end
end
I could write a test like this:
class MyMethodTest < Test::Unit::TestCase
def test_my_method
mock_block = mock
mock_directory_contents = mock
MyMethod.expects("`").with('ls').returns(mock_directory_contents)
Dir.expects(:chdir).yields(mock_block).returns(mock_directory_contents)
assert_equal mock_directory_contents, MyMethod.mymethod
end
end
Part of the trick is to figure out which object to expect the backtick method to be invoked on. It depends on the context - whatever self is when that method is invoked. Here it is the module MyMethod, but depending on where you define mymethod it will be different.

Ruby block parameter error

class MyClass
def test
...
end
end
tmp = MyClass.new
tmp.test do |t|
"here"
end
Why am I getting the error
multiple values for a block parameter (0 for 1)
Here is a slightly longer example, based on your code:
class MyClass
def test
yield self
end
def my_own_puts s
puts s
end
end
tmp = MyClass.new
tmp.test do |t|
t.my_own_puts "here"
end
Running this code will output "here".
What is happening is there is a method test that can take a block of code, so you can call it with the do .. end syntax. Because it is passing an arg to yield, that arg is available to the block, so you give this to the block using the do |some_arg_name| ... end syntax.
The yield is where the block gets executed in the test method, and in this case I to yield I pass in self. Since the block now has access to self (an instance of MyClass), the block can call the my_own_puts method on it, and print out "here".
if test is defined with a yield statement, when that statement is reached and if there is a parameter on the yield statement, that parameter will be put into the block variable t. Thus if you have:
def test
.....
yield x
......
end
then x will be the value of t when yield is executed.
With your help, I was able to get the code working like this
class MyClass
def test
a = yield self
puts a
end
end
tmp = MyClass.new
tmp.test do |t|
"here"
end
Thanks, I had to tweak your code a bit but it works the way I wanted to now.
Passing a block to a function (as Bob shows in his answer) is overkill in this case. If you are reading in a string and printing it out, all you should need is something like:
class MyClass
def test(a)
puts a
end
end
tmp = MyClass.new
tmp.test("here")
Using a block might function correctly, but you are calling a lot of unnecessary code and making the true nature of your code unclear.
Proper block usage aside, let me address the particular error message you are seeing. When you say tmp.test do |t|, Ruby is expecting tmp.test to yield a single value which it will temporarily call t and pass to the block (think like the block is a function and you are passing it the argument your yield statement as a parameter). In your case, the method test method must not be yield-ing anything, thus the message "(0 for 1)" implies that it is seeing zero objects yielded when it is expecting to see one. I don't know what your code for test does, but check and make sure that test yields exactly one value.

Resources