Skip to content

Instantly share code, notes, and snippets.

@theHamdiz
Last active March 18, 2016 05:17
Show Gist options
  • Select an option

  • Save theHamdiz/74d061a114e170724a99 to your computer and use it in GitHub Desktop.

Select an option

Save theHamdiz/74d061a114e170724a99 to your computer and use it in GitHub Desktop.
Extending TestCase functionality to add the more elegent must method, through some ruby metaprogramming magic
# Ruby Dose Facebook Page
require 'test/unit'
class Test::Unit::TestCase
def self.must(name, &block)
# convert "any method description" to any_method_description
test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
# don't define a new method if its already defined
defined = instance_method(test_name) rescue false
raise "#{test_name} is already defined on #{self}" if defined
if block_given?
# define the actual test_something_is_valid TestCase method
# pass it its functionality through a closure block
define_method(test_name, &block)
else
flunk "No implementation provided for #{name}"
end
end
end
# only use it if on another file otherwise leave it in the same file and don't require anything
# require_relative 'must'
module Store
class Product
def initialize(options = nil)
options.each { |p, v| instance_variable_set("@#{p}", v) } unless options.nil?
end
def price
defined = instance_variable_defined?(:@price)
raise "price is not set for this #{self.class.name.downcase}" unless defined
"#{@price} $"
end
end
end
class ProductTest < Test::Unit::TestCase
def setup
@empty_product = Store::Product.new
@full_product = Store::Product.new(price: 58)
end
must 'raise error if price is not set' do
assert_raise 'price is not set for this store::product' do
@empty_product.price
end
end
must 'return price plus dollar sign if price is set' do
assert_equal @full_product.price, '58 $'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment