[mocha-developer] using mocha with rspec

Jay Fields jay at jayfields.com
Sun Mar 18 09:17:43 EDT 2007


Hello Dan & James
The code below should provide the feature you are looking for.  It  
allows you to create an expectation like this:
obj.expects(:a_method).with(1, Fixnum, Object)
obj.a_method(1, 100, :anything)

Index: trunk/test/unit/expectation_test.rb
===================================================================
--- trunk/test/unit/expectation_test.rb (revision 109)
+++ trunk/test/unit/expectation_test.rb (working copy)
@@ -30,6 +30,16 @@
      assert expectation.match?(:expected_method, 1, 2, 3)
    end

+  def  
test_should_match_calls_to_same_method_with_expected_parameter_values_or 
_class
+    expectation = new_expectation.with(1, Fixnum, Object)
+    assert expectation.match?(:expected_method, 1, 2, 3)
+  end
+
+  def  
test_should_match_calls_to_same_method_with_expected_parameter_values_or 
_class
+    expectation = new_expectation.with(1, Fixnum, Object)
+    assert expectation.match?(:expected_method, 1, Fixnum, 3)
+  end
+
    def  
test_should_match_calls_to_same_method_with_parameters_constrained_as_ex 
pected
      expectation = new_expectation.with() {|x, y, z| x + y == z}
      assert expectation.match?(:expected_method, 1, 2, 3)
Index: trunk/lib/mocha/expectation.rb
===================================================================
--- trunk/lib/mocha/expectation.rb      (revision 109)
+++ trunk/lib/mocha/expectation.rb      (working copy)
@@ -22,9 +22,6 @@
      class InvalidExpectation < Exception; end

      class AlwaysEqual
-      def ==(other)
-        true
-      end
      end

      attr_reader :method_name, :backtrace
@@ -43,7 +40,15 @@
      end
      def match?(method_name, *arguments)
-      (@method_name == method_name) and (@parameter_block ?  
@parameter_block.call(*arguments) : (@parameters == arguments))
+      return false unless @method_name == method_name
+      return @parameter_block.call(*arguments) unless  
@parameter_block.nil?
+      return true if @parameters.is_a? AlwaysEqual
+      return false unless @parameters.size == arguments.size
+      @parameters.inject([0, true]) do |result, arg|
+        result[1] &&= (arguments[result.first].is_a?(Module) ? arg  
== arguments[result.first] : arg === arguments[result.first])
+        result[0] += 1
+        result
+      end.last
      end
      # :startdoc:

On Mar 13, 2007, at 8:41 AM, Dan North wrote:

> I came up with a hacky way of doing named matchers by using lambdas:
>
> first_arg_is_chewable = proc {|arg1, arg2| arg1.is_a? Chewable }
> # ...
> sheep.expects(:chew).with(&first_arg_is_chewable)
>
> which while readable is fugly :)  I used it when I wanted to reuse the
> same with-block.
>
> But yes, positional matchers would be much easier on both the eye and
> the brain!
>
> James Mead wrote:
>> On 13/03/07, Dan North <dan at tastapod.com> wrote:
>>
>>> The big things on my wishlist are:
>>>
>>> 1. Matchers in with(..) like JMock has:
>>> expects(:chew).with(is_a(Chewable), ANYTHING) where is_a(..) is a
>>> [something] that responds to matches?(actual) with true/false, and
>>> ANYTHING is a matcher that always returns true. That way, you  
>>> could use
>>> rspec's expectation matcher framework or roll your own matchers.  
>>> (I've
>>> got a bunch I wrote for my own mocking framework - everyone  
>>> should write
>>> a mocking framework at least twice once :)
>>>
>>> The method matches?(actual) seems fairly universal across these
>>> frameworks.
>>>
>>
>>
>> Something like this has been on the drawing board for a while.
>>
>> You can currently achieve something similar by using a block on  
>> the call to
>> with(), but I admit the syntax is not great.
>>
>> expects(:chew).with { |mouthful1, mouthful2| mouthful1.is_a? 
>> (Chewable) }
>>
>> 2. Type-aware mocks that fail with a NoMethodError if the underlying
>>
>>> type doesn't respond to an invoked method or method_missing (see  
>>> earlier
>>> thread).
>>>
>>
>>
>>
>> 3. Something akin to after(another_mock, :method).
>>
>>> None of these are showstoppers, but 1 is really high on my  
>>> priorities
>>> and 2 and 3 would make my life happier. I might try to roll  
>>> something
>>> for 1 if I get the time (read: unlikely!).
>>>
>>>
>>
>> Cool. My bandwidth is a bit limited at the moment too, but I'll  
>> see what we
>> can do.
>>
>> Thanks for your constructive suggestions.
>>
>>
>
> _______________________________________________
> mocha-developer mailing list
> mocha-developer at rubyforge.org
> http://rubyforge.org/mailman/listinfo/mocha-developer



More information about the mocha-developer mailing list