title: Rspec: How to test an exception is raised in private method?
body: <p>Getting error while testing an exception in a private method. How to test an exception is raised in private method which is called from a public method?</p>
  
  <p>Public</p>
  
  <pre><code>def public_method
      private_method
  end
  </code></pre>
  
  <p>Private</p>
  
  <pre><code>  def private_method
      tries = 0
      begin
        raise Product::StaleObjectError.new("Product is changed while you were editing") if stale_object?
        // Do some work
        raise Exception.new("Total amount used is greater than approved") if total_approved &lt; 0
  
        // Save Product
      rescue Product::StaleObjectError =&gt; e
        if tries &lt; MAX_RETRIES
          tries += 1
          sleep(1 + tries)
          reload
          retry
        else
          raise Product::StaleObjectError("Product is changed while you were editing")
        end
      end
      attributes
    end
  </code></pre>
  
  <p>Test Case:</p>
  
  <pre><code>  before(:each) do
      @prod_v1 = Product.new
    end
    it 'if product stale, then an exception should raise' do
      Product.any_instance.stub(:stale_object?).and_return(true)
      expect_any_instance_of(Product).to receive(:private_method).and_raise(Product::StaleObjectError.new("Product is changed while you were editing"), nil)
      @prod_v1.public_method
    end
  </code></pre>
  
  <p>I am getting following error for test case</p>
  
  <pre><code> Failure/Error: @product_v1.private_method
   Product::StaleObjectError:
     Product is changed while you were editing
   # ./app/models/product.rb:10:in `private_method'
   # ./spec/models/product_spec.rb:67:in `block (4 levels) in &lt;top (required)&gt;'
  </code></pre>
  
  <p>I tried the change the structure of the test case, but still get errors.</p>
  
  <pre><code>  it 'if product stale, then an exception should raise' do
     Product.any_instance.stub(:stale_object?).and_return(true)
      expect_any_instance_of(Product).to receive(:private_method).and_raise(Product::StaleObjectError.new(nil, nil))
      @prod_v1.public_method
    end
  </code></pre>
  
  <p>Error</p>
  
  <pre><code>    Failure/Error: expect_any_instance_of(Product).to receive(:private_method).and_raise(Product::StaleObjectError.new(nil, nil))
   ArgumentError:
     wrong number of arguments (2 for 0..1)
  </code></pre>