# In ruby you can mock everything, but get no indication when you forget to change underlying methods. | |
# In Java, this would be picked up by the compiler. | |
# This makes mocking in ruby more fragile. | |
# What if you were only allowed to mock methods on an "interface"? In the simple case | |
# this is just a class, but could be a module for re-use. | |
require 'minitest/unit' | |
require 'minitest/mock' | |
require 'minitest/autorun' | |
class UserDAO | |
def update_email(email) | |
# ... | |
end | |
end | |
class UserUpdater | |
def update_details(dao, attributes) | |
dao.update_name_and_email(attributes[:name], attributes[:email]) | |
end | |
end | |
class InterfaceMock < MiniTest::Mock | |
def initialize(interface) | |
@interface = interface | |
super() | |
end | |
def expect(method_name, *args) | |
unless @interface.instance_methods(false).include?(method_name) | |
raise "Attempted to stub #{method_name} which doesn't exist on #{@interface}" | |
end | |
super | |
end | |
end | |
class UserUpdaterTest < MiniTest::Unit::TestCase | |
def test_update_details_updates_email | |
dao = InterfaceMock.new(UserDAO) | |
# dao = MiniTest::Mock.new | |
dao.expect(:update_name_and_email, nil, ['don', 'hello@example.com']) | |
updater = UserUpdater.new | |
updater.update_details(dao, name: 'don', email: 'hello@example.com') | |
dao.verify | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment