1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/activesupport/test/testing/method_call_assertions_test.rb
bogdanvlviv 9d0cf52096
assert_called_with should require args argument
There are two main reasons why `assert_called_with` should require
`args` argument:

1) If we want to assert that some method should be called and we don't
   need to check with which arguments it should be called then we should use
   `assert_called`.

2) `assert_called_with` without `args` argument doesn't assert anything!
   ```ruby
   assert_called_with(@object, :increment) do
      @object.decrement
   end
   ```
   It causes false assertions in tests that could cause regressions in the project.

I found this bug by working on
[minitest-mock_expectations](https://github.com/bogdanvlviv/minitest-mock_expectations) gem.
This gem is an extension for minitest that provides almost the same method call
assertions.
I was wondering whether you would consider adding "minitest-mock_expectations"
to `rails/rails` instead of private `ActiveSupport::Testing::MethodCallAssertions` module.
If yes, I'll send a patch - a970ecc42c
2018-10-25 21:29:39 +03:00

203 lines
5 KiB
Ruby

# frozen_string_literal: true
require "abstract_unit"
class MethodCallAssertionsTest < ActiveSupport::TestCase
class Level
def increment; 1; end
def decrement; end
def <<(arg); end
end
setup do
@object = Level.new
end
def test_assert_called_with_defaults_to_expect_once
assert_called @object, :increment do
@object.increment
end
end
def test_assert_called_more_than_once
assert_called(@object, :increment, times: 2) do
@object.increment
@object.increment
end
end
def test_assert_called_method_with_arguments
assert_called(@object, :<<) do
@object << 2
end
end
def test_assert_called_returns
assert_called(@object, :increment, returns: 10) do
assert_equal 10, @object.increment
end
assert_equal 1, @object.increment
end
def test_assert_called_failure
error = assert_raises(Minitest::Assertion) do
assert_called(@object, :increment) do
# Call nothing...
end
end
assert_equal "Expected increment to be called 1 times, but was called 0 times.\nExpected: 1\n Actual: 0", error.message
end
def test_assert_called_with_message
error = assert_raises(Minitest::Assertion) do
assert_called(@object, :increment, "dang it") do
# Call nothing...
end
end
assert_match(/dang it.\nExpected increment/, error.message)
end
def test_assert_called_with_arguments
assert_called_with(@object, :<<, [ 2 ]) do
@object << 2
end
end
def test_assert_called_with_arguments_and_returns
assert_called_with(@object, :<<, [ 2 ], returns: 10) do
assert_equal(10, @object << 2)
end
assert_nil(@object << 2)
end
def test_assert_called_with_failure
assert_raises(MockExpectationError) do
assert_called_with(@object, :<<, [ 4567 ]) do
@object << 2
end
end
end
def test_assert_called_with_multiple_expected_arguments
assert_called_with(@object, :<<, [ [ 1 ], [ 2 ] ]) do
@object << 1
@object << 2
end
end
def test_assert_called_on_instance_of_with_defaults_to_expect_once
assert_called_on_instance_of Level, :increment do
@object.increment
end
end
def test_assert_called_on_instance_of_more_than_once
assert_called_on_instance_of(Level, :increment, times: 2) do
@object.increment
@object.increment
end
end
def test_assert_called_on_instance_of_with_arguments
assert_called_on_instance_of(Level, :<<) do
@object << 2
end
end
def test_assert_called_on_instance_of_returns
assert_called_on_instance_of(Level, :increment, returns: 10) do
assert_equal 10, @object.increment
end
assert_equal 1, @object.increment
end
def test_assert_called_on_instance_of_failure
error = assert_raises(Minitest::Assertion) do
assert_called_on_instance_of(Level, :increment) do
# Call nothing...
end
end
assert_equal "Expected increment to be called 1 times, but was called 0 times.\nExpected: 1\n Actual: 0", error.message
end
def test_assert_called_on_instance_of_with_message
error = assert_raises(Minitest::Assertion) do
assert_called_on_instance_of(Level, :increment, "dang it") do
# Call nothing...
end
end
assert_match(/dang it.\nExpected increment/, error.message)
end
def test_assert_called_on_instance_of_nesting
assert_called_on_instance_of(Level, :increment, times: 3) do
assert_called_on_instance_of(Level, :decrement, times: 2) do
@object.increment
@object.decrement
@object.increment
@object.decrement
@object.increment
end
end
end
def test_assert_not_called
assert_not_called(@object, :decrement) do
@object.increment
end
end
def test_assert_not_called_failure
error = assert_raises(Minitest::Assertion) do
assert_not_called(@object, :increment) do
@object.increment
end
end
assert_equal "Expected increment to be called 0 times, but was called 1 times.\nExpected: 0\n Actual: 1", error.message
end
def test_assert_not_called_on_instance_of
assert_not_called_on_instance_of(Level, :decrement) do
@object.increment
end
end
def test_assert_not_called_on_instance_of_failure
error = assert_raises(Minitest::Assertion) do
assert_not_called_on_instance_of(Level, :increment) do
@object.increment
end
end
assert_equal "Expected increment to be called 0 times, but was called 1 times.\nExpected: 0\n Actual: 1", error.message
end
def test_assert_not_called_on_instance_of_nesting
assert_not_called_on_instance_of(Level, :increment) do
assert_not_called_on_instance_of(Level, :decrement) do
# Call nothing...
end
end
end
def test_stub_any_instance
stub_any_instance(Level) do |instance|
assert_equal instance, Level.new
end
end
def test_stub_any_instance_with_instance
stub_any_instance(Level, instance: @object) do |instance|
assert_equal @object, instance
assert_equal instance, Level.new
end
end
end