Skip to content

Instantly share code, notes, and snippets.

@fernandes
Created February 21, 2020 13:32
Show Gist options
  • Save fernandes/5e8f687892a232fc9e32030a53329112 to your computer and use it in GitHub Desktop.
Save fernandes/5e8f687892a232fc9e32030a53329112 to your computer and use it in GitHub Desktop.
Example for "Interface" and "Concrete" class in Ruby
require 'test_helper'
# Add the `described_class` so it can be used in the AutoInterfaceTest
class ActiveSupport::TestCase
def described_class
self.class.to_s.gsub(/Test$/, '').constantize
end
end
# In the interface, the example Auto - Car is dummy, because it should be
# an instance, and instance method, but as you asked for class methods
# it's the same idea
module Auto
# Do not use Ruby's NotImplementedError, that is reserved for platform methods
# create your own inside the module
class NotImplementedError < StandardError; end
def self.included(base)
base.extend(ClassMethods)
end
# methods to be implemented
module ClassMethods
def start
raise NotImplementedError.new('Must implement start')
end
def stop
raise NotImplementedError.new('Must implement stop')
end
end
end
# Esse é o teste da interface, testa que ela força a implementação do start/stop
class AutoTest < ActiveSupport::TestCase
class ImplementAuto
# it extends `ClassMethods` on base
# so you can add instance and class methods
include Auto
end
test "raise error for start" do
err = assert_raises(Auto::NotImplementedError) { ImplementAuto.start }
assert_match('Must implement start', err.message)
end
test "raise error for stop" do
err = assert_raises(Auto::NotImplementedError) { ImplementAuto.start }
assert_match('Must implement start', err.message)
end
end
# This module tests the interface and you need to add on your test
# so it tests the implemented methods, same as rspec's shared_examples
module AutoInterfaceTest
def test_must_respond_to_start
described_class.send(:stop)
end
def test_must_respond_to_stop
described_class.send(:stop)
end
end
# The 'Concrete' class
class Car
extend Auto
class << self
# If you comment the methods below, CarTest will fail
def start
true
end
def stop
true
end
end
end
# The of the "concrete" class, ensure the interface is implemented
class CarTest < ActiveSupport::TestCase
include AutoInterfaceTest
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment