<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Gluttonous: Injecting Mocks (one way or another)</title>
    <link>http://glu.ttono.us/articles/2006/08/30/injecting-mocks-one-way-or-another</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Injecting Mocks (one way or another)</title>
      <description>&lt;p&gt;I&amp;#8217;ve been playing a lot with mocks lately (and I&amp;#8217;m a bit post happy today) so I thought I&amp;#8217;d show off a bit of code that was useful in a &lt;a href="http://dev.rubyonrails.org/ticket/5970"&gt;patch&lt;/a&gt; in RailTies.&lt;/p&gt;

&lt;p&gt;Sometimes methods are hard to mock. They aren&amp;#8217;t calling actions on some object you can replace with a mock or the API was designed so it&amp;#8217;s hard to inject the mock in the first place.&lt;/p&gt;

&lt;p&gt;This bit of code lets you intercept a method call and redirect it to a mock object of your choosing:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  
  &lt;span class="comment"&gt;# The multiple method form&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;delegate_methods_to_mock!&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;methods&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;methods&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;m&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;redefine_method_using_mock!&lt;/span&gt; &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;m&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;yield&lt;/span&gt;
    &lt;span class="ident"&gt;methods&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;m&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;reset_method_using_mock!&lt;/span&gt; &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;m&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;delegate_method_to_mock!&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;redefine_method_using_mock!&lt;/span&gt; &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;
    &lt;span class="keyword"&gt;yield&lt;/span&gt;
    &lt;span class="ident"&gt;reset_method_using_mock!&lt;/span&gt; &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;redefine_method_using_mock!&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:attr_writer&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:mock&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;respond_to?&lt;/span&gt; &lt;span class="symbol"&gt;:mock=&lt;/span&gt;

    &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:alias_method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;nonmocked_&lt;span class="expr"&gt;#{method.to_s}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;respond_to?&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;nonmocked_&lt;span class="expr"&gt;#{method.to_s}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

    &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:define_method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; 
      &lt;span class="constant"&gt;Proc&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="punct"&gt;{|*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="attribute"&gt;@mock&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;reset_method_using_mock!&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:remove_method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;klass&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:alias_method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;method&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;nonmocked_&lt;span class="expr"&gt;#{method.to_s}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So then we use it like:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;test_process_exit&lt;/span&gt;
    &lt;span class="ident"&gt;delegate_methods_to_mock!&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;RailsFCGIHandler&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:close_connection&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="ident"&gt;fcgi&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;flexmock&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
      &lt;span class="ident"&gt;fcgi&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_receive&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:close_connection&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@handler&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;mock&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;fcgi&lt;/span&gt;
      &lt;span class="attribute"&gt;@handler&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;stubs&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:when_ready&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;returns&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:exit&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@handler&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;process!&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What happens is that an accessor is placed on the object in question and the method you want the mock to intercept is redirected to call on the mock instead&amp;#8230; so it goes like this:&lt;/p&gt;

&lt;p&gt;I call someobject.blah(1,2,3) which would normally call someobject.a(1,2,3) (may be a protected method) but instead we redefine a to call @mock.a(1,2,3) so we can register the call.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not entirely sure if this is the best way to handle it but it seems to be working for my needs at the moment.&lt;/p&gt;</description>
      <pubDate>Wed, 30 Aug 2006 17:15:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:4305ee1d-cb83-4769-a0c6-11c34eb70bd2</guid>
      <author>kev</author>
      <link>http://glu.ttono.us/articles/2006/08/30/injecting-mocks-one-way-or-another</link>
      <category>Rails</category>
      <category>Ruby</category>
      <category>testing</category>
    </item>
    <item>
      <title>"Injecting Mocks (one way or another)" by Kevin Clark</title>
      <description>&lt;p&gt;James,
It does indeed. That&amp;#8217;s why I contacted you about the licensing.&lt;/p&gt;</description>
      <pubDate>Thu, 31 Aug 2006 12:42:59 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:bea10158-6e04-4867-a3ae-18d488e74ac8</guid>
      <link>http://glu.ttono.us/articles/2006/08/30/injecting-mocks-one-way-or-another#comment-1076</link>
    </item>
    <item>
      <title>"Injecting Mocks (one way or another)" by James Mead</title>
      <description>&lt;p&gt;This looks very similar to early versions of the Stubba component of &lt;a href="http://mocha.rubyforge.org"&gt;Mocha&lt;/a&gt;. We also started off using blocks, but found the syntax quickly becomes less readable when you want to mock multiple methods, or even multiple methods on multiple classes &amp;#8211; this is why I moved to using the TestCase teardown to revert classes back to their original definition. Another evolution of Mocha was to add the &amp;#8220;expects&amp;#8221; and &amp;#8220;stubs&amp;#8221; methods to the Object class to make the tests even more readable.&lt;/p&gt;


	&lt;p&gt;If I&amp;#8217;m not mistaken, your example above includes use of Mocha does it not?&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;  @handler.stubs(:when_ready).returns(:exit)&lt;/code&gt;&lt;/pre&gt;</description>
      <pubDate>Thu, 31 Aug 2006 06:23:10 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:651f88db-6f78-42cd-b86d-630545584864</guid>
      <link>http://glu.ttono.us/articles/2006/08/30/injecting-mocks-one-way-or-another#comment-1068</link>
    </item>
    <item>
      <title>"Injecting Mocks (one way or another)" by Rails</title>
      <description>&lt;p&gt;Excellent explanation here for the Mock injection. I&amp;#8217;m also pretty sure there&amp;#8217;s other ways of handling that but nothing springs to mind off the top&amp;#8230;&lt;/p&gt;</description>
      <pubDate>Wed, 30 Aug 2006 19:58:38 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:9ff825d2-7ea8-4a6f-b074-315e3e85717a</guid>
      <link>http://glu.ttono.us/articles/2006/08/30/injecting-mocks-one-way-or-another#comment-1053</link>
    </item>
  </channel>
</rss>

