Created
February 21, 2020 13:32
-
-
Save fernandes/5e8f687892a232fc9e32030a53329112 to your computer and use it in GitHub Desktop.
Example for "Interface" and "Concrete" class in Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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