Code Monkey home page Code Monkey logo

rspec-mocks's People

Contributors

alexdowad avatar alindeman avatar askreet avatar benoittgt avatar bryanp avatar cupakromer avatar dchelimsky avatar eregon avatar jferris avatar jonrowe avatar jredville avatar justinko avatar kaiwren avatar mame avatar mauricio avatar mvz avatar myronmarston avatar olleolleolle avatar orend avatar pda avatar phiggins avatar pirj avatar preethiramdev avatar soulcutter avatar spicycode avatar timcowlishaw avatar tjallingvanderwal avatar xaviershay avatar yujinakayama avatar zhisme avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rspec-mocks's Issues

Invoking 'with' after an 'and_return' should raise a NoMethodError

I ran into this when working on #10
it "raises an error if 'with' follows 'and_return'" do
lambda do
foo = ""
foo.should_receive(:foo).and_return(1).with("1")
foo.foo('')
end.should raise_error(NoMethodError)
end

instead of passing this produces
().foo(any args)
expected: 1 time
received: 0 times

Clearly, the with is being ignored entirely. Interestingly, replacing should_receive with stub makes this test pass.

any_instance doesn't work with stub! alias

Defining stubs on any instance of an object doesn't work when using the stub! method. This scenario fails:

  Scenario: simple any_instance stub with a single return value using the stub! alias
    Given a file named "example_spec.rb" with:
      """
      describe "any_instance.stub!" do
        it "returns the specified value on any instance of the class" do
          Object.any_instance.stub!(:foo).and_return(:return_value)

          o = Object.new
          o.foo.should eq(:return_value)
        end
      end
      """
    When I run `rspec example_spec.rb`
    Then the examples should all pass

at_least(:once) doesn't work as documented

Example:
@obj = Object.new
@obj.should_receive(:to_s).at_least(:once) {"testing"}
@obj.to_s.should == "testing"

Upper test fails. It works if I modify the expectation line like that, but doesn't read right:
@obj.should_receive(:to_s).at_least(:once).times {"testing"}

Mock#to_ary and Array#flatten problem...

No better way to describe this then:
http://floehopper.lighthouseapp.com/projects/22289-mocha/tickets/70

Ran into this while trying to run specs for Formtastic in 1.9.2. Problem with just stubbing it is it then breaks other tests because rails uses respond_to?(:to_ary) internally which breaks other tests in formtastic...

Rspec response:
Mock "user" received unexpected message :to_ary with (no args)
# ./lib/formtastic.rb:575:in flatten' # ./lib/formtastic.rb:575:ininputs_for_nested_attributes'
# ./lib/formtastic.rb:280:in inputs' # ./spec/inputs_spec.rb:439:inblock (6 levels) in <top (required)>'
# ./lib/formtastic.rb:1927:in block in semantic_form_for' # ./lib/formtastic.rb:1892:inwith_custom_field_error_proc'
# ./lib/formtastic.rb:1926:in semantic_form_for' # ./spec/inputs_spec.rb:438:inblock (5 levels) in <top (required)>'

Let me know what else is needed...

#should_receive(:meth).with(...) and #should_receive(:meth).once should be_compatible

Currently, if I try to specify both:

obj.should_receive(:message).with(...something...)
obj.should_receive(:message).with(...something...else...)

and

obj.should_receive(:message).twice

the latter expectation is reported unmet.

I have found a workaround which is obj.should_receive(:message).never instead of ....twice (note that for a reason unfortunately unknown obj.should_receive(:message).never is not the same as obj.should_not_receive(:message) here), but it leads to specs slightly less comprehensible than I would like them to be.

rspec-mocks spec build breaks on JRuby 1.6.0/1.6.1 even though all tests pass

I only just noticed this when I added a build of rspec-mocks on JRuby to our CI instance.

~/Work/Rspec/rspec-mocks (master)λ rake spec                              jruby-1.6.1@rspecmocks
(in /Users/sidu/Work/Rspec/rspec-mocks)
zsh:1: no matches found: bin/*
zsh:1: no matches found: bin/*
zsh:1: no matches found: spec/*
zsh:1: no matches found: bin/*
zsh:1: no matches found: bin/*
/Users/sidu/.rvm/rubies/jruby-1.6.1/bin/jruby -S bundle exec rspec --color ./spec/rspec/mocks_spec.rb ./spec/rspec/mocks/and_yield_spec.rb ./spec/rspec/mocks/any_instance_spec.rb ./spec/rspec/mocks/any_number_of_times_spec.rb ./spec/rspec/mocks/argument_expectation_spec.rb ./spec/rspec/mocks/at_least_spec.rb ./spec/rspec/mocks/at_most_spec.rb ./spec/rspec/mocks/block_return_value_spec.rb ./spec/rspec/mocks/bug_report_10260_spec.rb ./spec/rspec/mocks/bug_report_10263_spec.rb ./spec/rspec/mocks/bug_report_11545_spec.rb ./spec/rspec/mocks/bug_report_496_spec.rb ./spec/rspec/mocks/bug_report_600_spec.rb ./spec/rspec/mocks/bug_report_7611_spec.rb ./spec/rspec/mocks/bug_report_8165_spec.rb ./spec/rspec/mocks/bug_report_830_spec.rb ./spec/rspec/mocks/bug_report_957_spec.rb ./spec/rspec/mocks/double_spec.rb ./spec/rspec/mocks/failing_argument_matchers_spec.rb ./spec/rspec/mocks/hash_including_matcher_spec.rb ./spec/rspec/mocks/hash_not_including_matcher_spec.rb ./spec/rspec/mocks/mock_ordering_spec.rb ./spec/rspec/mocks/mock_space_spec.rb ./spec/rspec/mocks/mock_spec.rb ./spec/rspec/mocks/multiple_return_value_spec.rb ./spec/rspec/mocks/nil_expectation_warning_spec.rb ./spec/rspec/mocks/null_object_mock_spec.rb ./spec/rspec/mocks/once_counts_spec.rb ./spec/rspec/mocks/options_hash_spec.rb ./spec/rspec/mocks/partial_mock_spec.rb ./spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb ./spec/rspec/mocks/passing_argument_matchers_spec.rb ./spec/rspec/mocks/precise_counts_spec.rb ./spec/rspec/mocks/record_messages_spec.rb ./spec/rspec/mocks/serialization_spec.rb ./spec/rspec/mocks/stash_spec.rb ./spec/rspec/mocks/stub_chain_spec.rb ./spec/rspec/mocks/stub_implementation_spec.rb ./spec/rspec/mocks/stub_spec.rb ./spec/rspec/mocks/stubbed_message_expectations_spec.rb ./spec/rspec/mocks/to_ary_spec.rb ./spec/rspec/mocks/twice_counts_spec.rb
zsh:1: no matches found: bin/*
zsh:1: no matches found: bin/*
zsh:1: no matches found: spec/*
zsh:1: no matches found: bin/*
Run filtered excluding {:ruby=>#<Proc:/Users/sidu/Work/Rspec/rspec-mocks/spec/spec_helper.rb:42>}
................**....................................................................................................................................................................................................................................................................................................................................................................................................................................

Pending:
  #any_instance invocation order#should_receive raises an error if 'with' follows 'and_return'
    # see Github issue #42
    # ./spec/rspec/mocks/any_instance_spec.rb:40
  #any_instance invocation order#should_receive raises an error if 'with' follows 'and_raise'
    # see Github issue #42
    # ./spec/rspec/mocks/any_instance_spec.rb:45

Finished in 3.94 seconds
438 examples, 0 failures, 2 pending
rake aborted!
ruby -S bundle exec rspec --color ./spec/rspec/mocks_spec.rb ./spec/rspec/mocks/and_yield_spec.rb ./spec/rspec/mocks/any_instance_spec.rb ./spec/rspec/mocks/any_number_of_times_spec.rb ./spec/rspec/mocks/argument_expectation_spec.rb ./spec/rspec/mocks/at_least_spec.rb ./spec/rspec/mocks/at_most_spec.rb ./spec/rspec/mocks/block_return_value_spec.rb ./spec/rspec/mocks/bug_report_10260_spec.rb ./spec/rspec/mocks/bug_report_10263_spec.rb ./spec/rspec/mocks/bug_report_11545_spec.rb ./spec/rspec/mocks/bug_report_496_spec.rb ./spec/rspec/mocks/bug_report_600_spec.rb ./spec/rspec/mocks/bug_report_7611_spec.rb ./spec/rspec/mocks/bug_report_8165_spec.rb ./spec/rspec/mocks/bug_report_830_spec.rb ./spec/rspec/mocks/bug_report_957_spec.rb ./spec/rspec/mocks/double_spec.rb ./spec/rspec/mocks/failing_argument_matchers_spec.rb ./spec/rspec/mocks/hash_including_matcher_spec.rb ./spec/rspec/mocks/hash_not_including_matcher_spec.rb ./spec/rspec/mocks/mock_ordering_spec.rb ./spec/rspec/mocks/mock_space_spec.rb ./spec/rspec/mocks/mock_spec.rb ./spec/rspec/mocks/multiple_return_value_spec.rb ./spec/rspec/mocks/nil_expectation_warning_spec.rb ./spec/rspec/mocks/null_object_mock_spec.rb ./spec/rspec/mocks/once_counts_spec.rb ./spec/rspec/mocks/options_hash_spec.rb ./spec/rspec/mocks/partial_mock_spec.rb ./spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb ./spec/rspec/mocks/passing_argument_matchers_spec.rb ./spec/rspec/mocks/precise_counts_spec.rb ./spec/rspec/mocks/record_messages_spec.rb ./spec/rspec/mocks/serialization_spec.rb ./spec/rspec/mocks/stash_spec.rb ./spec/rspec/mocks/stub_chain_spec.rb ./spec/rspec/mocks/stub_implementation_spec.rb ./spec/rspec/mocks/stub_spec.rb ./spec/rspec/mocks/stubbed_message_expectations_spec.rb ./spec/rspec/mocks/to_ary_spec.rb ./spec/rspec/mocks/twice_counts_spec.rb failed

(See full trace by running task with --trace)

Stub chain not working

I have a spec where I do

    User.any_instance.stub_chain(:challenges, :won){
      [ @challenge1, @challenge2 ]
    }

but I get the error

undefined method `playback!' for nil:NilClass
/Users/bradphelan/.rvm/gems/ruby-1.9.2-p180@mysugrapp/gems/activesupport-3.1.0.rc5/lib/active_support/whiny_nil.rb:48:in `method_missing'
/Users/bradphelan/.rvm/gems/ruby-1.9.2-p180@mysugrapp/gems/rspec-mocks-2.6.0/lib/rspec/mocks/any_instance.rb:134:in `playback!'
/Users/bradphelan/.rvm/gems/ruby-1.9.2-p180@mysugrapp/gems/rspec-mocks-2.6.0/lib/rspec/mocks/any_instance.rb:221:in `challenges'
/Users/bradphelan/workspace/mysugr/mysugrapp/app/controllers/challenges_controller.rb:34:in `index_won'

a bit of digging and I modified the code in any_instance to look like

----------------------
/Users/bradphelan/.rvm/gems/ruby-1.9.2-p180@mysugrapp/gems/rspec-mocks-2.6.0/lib/rspec/mocks/any_instance.rb
----------------------
129         def playback!(instance, method_name)
130           RSpec::Mocks::space.add(instance)
131           puts 'BPH'
132           pp @message_chains
133           pp method_name
134           @message_chains[method_name].playback!(instance)
135           @played_methods[method_name] = instance
136           received_expected_message!(method_name) if has_expectation?(method_name)
137         end

The output at this point in the code was

BPH
{"challenges"=>
  #<RSpec::Mocks::AnyInstance::StubChain:0x00000106718020
   @invocation_order=
    {:stub=>[nil],
     :with=>[:stub],
     :and_return=>[:with, :stub],
     :and_raise=>[:with, :stub],
     :and_yield=>[:with, :stub]},
   @messages=
    [[[:stub, "challenges"],
      #<Proc:0x00000106718c50@/Users/bradphelan/.rvm/gems/ruby-1.9.2-p180@mysugrapp/gems/rspec-mocks-2.6.0/lib/rspec/mocks/methods.rb:45>]]>}
:challenges

It seems the key in the hash is a string "challenges" but the hash is being indexed by the symbol :challenges and
returns null and therefore the crash.

I modified the source code to

    def playback!(instance, method_name)
      RSpec::Mocks::space.add(instance)
      method_name = method_name.to_s
      @message_chains[method_name].playback!(instance)
      @played_methods[method_name] = instance
      received_expected_message!(method_name) if has_expectation?(method_name)
    end

and now my spec works

unstub method to remove a stub is missing

unstub / unstub! is not available in rspec-mocks 2.0.0.beta7. Since it's rather handy to be able to remove som stubs mid-test I would like to see it implemented in rspec 2.0

Bulk test double declaration with `doubles *args`

Hi David,

I often find myself declaring a bunch of test doubles with no stubs on them, just dummy objects I can pass around to isolate the spec. An example:

it 'does something' do
  logger = double :logger
  foo = double :foo
  bar = double :bar

  # Pass these objects around
  ...
end

I'm wondering whether it would be useful to declare these dummy objects in bulk, like this:

it 'does something' do
  doubles :logger, :foo, :bar #sets the variables logger, foo and bar to dummy test doubles
  ...
end

I'm thinking it might have more sense to move this idiom +outside+ the examples:

describe 'some example group' do
  doubles :logger, :foo, :bar #would be equivalent to let(:logger) { double :logger }, let(:foo)...

  it 'does something' do
    # here logger, foo, and bar are available in every example inside this context block
  end

Do you have any feedback on these? I don't think it makes the examples any less readable, so it might be useful to avoid cluttering examples with cumbersome dummy object declaration. I'd be happy to implement it if it goes through. What do you think?

Using a block when calling #with is awkward

If you write obj.stub(:foo).with(1) {5} with the intention that 5 will be the return value, you'll likely be surprised when you discover that the block is also being used as an argument matcher and that the code will match invocation like obj.foo(2) etc.

Message expectation counts don't work in combination with a stub

Spec:

class MyClass
  def initialize(dependency)
    @dependency = dependency
  end

  def calculate_value
    @dependency.foo
  end
end

describe MyClass, '#calculate_value' do
  let(:dependency) { Object.new }
  subject { MyClass.new(dependency) }

  context 'when dependency.foo returns :bar' do
    before(:each) { dependency.stub(:foo).and_return(:bar) }

    it 'returns :bar' do
      subject.calculate_value.should == :bar
    end

    it 'memoizes the value so dependency.foo is not invoked multiple times' do
      dependency.should_receive(:foo).once
      3.times { subject.calculate_value }
    end
  end
end

These specs pass:

$ rspec rspec_example.rb       
..

Finished in 0.00199 seconds
2 examples, 0 failures

...but the 2nd example should fail. If I comment out the before(:each), then it properly fails.

Test failure on JRuby 1.6.0

Running rake for rspec-mocks against Jruby-1.6.0 on OSX against ef127a5 has nil_expectation_warning_spec.rb fail with the trace given at the end of this ticket.

The failure seems to be occurring because jruby returns a failure trace with
Called from #{FILE}:#{LINE+3}:in (class Mocks)' instead of what CRuby returns which is Called from #{__FILE__}:#{__LINE__+3}(:inblock (2 levels) in module:Mocks

These strings are generated by caller[4] so this might actually be a JRuby issue (which I will check and confirm).

Trace:
1) an expectation set on nil issues a warning with file and line number information
Failure/Error: nil.should_receive(:foo)
Kernel received :warn with unexpected arguments
expected: (/An expectation of :foo was set on nil. Called from /Users/sidu/Work/Rspec/rspec-mocks/spec/rspec/mocks/nil_expectation_warning_spec.rb:21(:in block \(2 levels\) in <module:Mocks>')?. Use allow_message_expectations_on_nil to disable warnings./) got: ("An expectation of :foo was set on nil. Called from /Users/sidu/Work/Rspec/rspec-mocks/spec/rspec/mocks/nil_expectation_warning_spec.rb:21:in(class Mocks)'. Use allow_message_expectations_on_nil to disable warnings.")
# ./spec/rspec/mocks/nil_expectation_warning_spec.rb:21:in (class Mocks)' # org/jruby/RubyKernel.java:2007:ininstance_eval'
# org/jruby/RubyArray.java:2306:in collect' # org/jruby/RubyArray.java:2306:incollect'

any_instance is not instance-agnostic when using receiver count expectation

I'm trying to set up a spec like this:

  class Calc
  end

  context "any_instance with receiver count expectation" do
    before do
      Calc.any_instance.should_receive(:add).twice
    end

    it 'should work with multiple instances' do
      Calc.new.add(1,2)
      Calc.new.add(2,3)
    end

This doesn't work, it generates an error:

RSpec::Mocks::MockExpectationError: The message 'add' was received by #<Calc:0x884cdc8> but has already been received by #<Calc:0x884f9d8>

I'm concluding that when using a receiver count expectation any_instance is specific to a given instance, counter to the assumption that any_instance really should work with any instance.

What I actually want to do is to be able to define multiple argument expectations with this, along the lines of:

Calc.any_instance.should_receive(:add).with(1,2).and_return(3)
Calc.any_instance.should_receive(:add).with(2,3).and_return(5)

That totally breaks down. The simple calculator example here is for illustration only, my actual issue is more complex and I can't easily compute the return value, but have to rely on table look-ups. In other words, I've not found a suitable work-around and I really need this behavior as described above, if it's supposed to be supported (which I'm not sure of).

I don't know if it matters: I'm doing this with Rails 3, RSpec 2.6, and Ree Ruby 1.8.7

Mocks set "as_null_object" should give a warning when they receive a "should_recieve" message

I know that mocks defined to be "as_null_object" are supposed to swallow all messages they receive, but that can lead to some tests succeeding when they in fact should fail.

In particular, the "should_*" expectations should at least trigger a warning that the code has a potential misspelling. This is a "nice to have" feature for programmers (like me) who sometimes mispel wrds and mehtods sent to mocks.

Here is some example code.

require 'rubygems'
require 'rspec'

class Foo; end

describe Foo do
  it "should give a warning on this test that 'should_recieve' is a potential misspelling" do
    m = mock.as_null_object
    m.should_recieve(:new)
    m.new
  end
end

hash form of stub_chain returning nil for chains with shared first message Options

I'd expect this to pass (using rspec 2.5.1)

describe 'stub_chain' do 
  it "returns expected value from two chains with hash" do 
    subject = Object.new 
    subject.stub_chain(:msg1, :msg2 => :first) 
    subject.stub_chain(:msg1, :msg3 => :second) 
    subject.msg1.msg2.should equal(:first) 
    subject.msg1.msg3.should equal(:second) 
  end 
end   

But it doesn't - subject.msg1.msg3 returns nil

Can't use unstub with any_instance

test_model.rb

class TestModel
  def meth
    raise 'meth called'
  end
end

test_model_spec.rb

require 'spec_helper'

describe TestModel do
  before do
    TestModel.any_instance.stub(:meth)
  end

  it 'should be stubbed' do
    lambda { TestModel.new.meth }.should_not raise_error
  end

  it 'should be able to unstub' do
    TestModel.any_instance.unstub(:meth)
    lambda { TestModel.new.meth }.should raise_error
  end
end

rspec test_model_spec.rb -f d

TestModel
  should be stubbed
  should be able to unstub (FAILED - 1)

Failures:

  1) TestModel should be able to unstub
     Failure/Error: TestModel.any_instance.unstub(:meth)
       The method `meth` was not stubbed or was already unstubbed
     # test_model_spec.rb:13

PS. I think we're all robots here speaking code&specs :)

Undefined method stub report

As discussed on the mailing list, I've started the work on adding an undefined method stub report in a branch. I've got things to the point where I've recorded all the various bits of info, and now we just need to add the code to print the report. Since there wasn't much feedback from others, I figured it'd be easiest to nail down the details here, but we can take the conversation back to the mailing list if you'd prefer.

For reference, here's the current documentation output for the UndefinedMethodDouble specs:

RSpec::Mocks::UndefinedMethodDouble
  when recording is disabled
    a stub of a previously undefined method
      is not recorded
    a mock of a previously undefined method
      is not recorded
  when recording is enabled
    a stub of a previously defined method
      is not recorded
    a stub of a previously undefined method
      is not recorded when the method is defined before the invocation
      when the method double is defined and invoked once
        records the stubed object
        records the stubed method
        records the invocation
        records the definition
        for a pure mock object
          is not recorded
        for a pure stub object
          is not recorded
        for a pure double object
          is not recorded
      when the method double is defined once and invoked twice
        records only a single stubed object
        records only a single stubed method
        records only a single definition
        records each invocation
      when the method double is defined twice and invoked once
        records only a single stubed object
        records only a single stubed method
        records each definition
        records only a single invocation
    a mock of a previously defined method
      is not recorded
    a mock of a previously undefined method
      is not recorded when the method is defined before the invocation
      when the method double is defined and invoked once
        records the mocked object
        records the mocked method
        records the invocation
        records the definition
        for a pure mock object
          is not recorded
        for a pure stub object
          is not recorded
        for a pure double object
          is not recorded
      when the method double is defined once and invoked twice
        records only a single mocked object
        records only a single mocked method
        records only a single definition
        records each invocation
      when the method double is defined twice and invoked once
        records only a single mocked object
        records only a single mocked method
        records each definition
        records only a single invocation

David, at this point, I could use some input from you.

  • I'd like to record the running example at the time that each undefined method double is invoked, but I couldn't find a way to access that. Is there something I'm missing?
  • I'm not sure of the best way to hook this in to the formatters. Do we care to provide this report for non-text formatters? I guess maybe the html formatter could just wrap it in a big <pre> block.
  • At which point in the reportor should it go? I was thinking that it could go at the start of #dump_summary.
  • I'm not sure of the best way to implement this in a mock-framework-agnostic way. How does this sound? In addition to the current three methods we have on the mock adapters (setup_mocks_for_rspec, verify_mocks_for_rspec and teardown_mocks_for_rspec), we can add an (optional) fourth method: print_summary_for_rspec. For now, rspec-mocks would be the only one to actually do anything here, but in the future if any of the other mocking libraries provide similar functionality, they'd have a place to hook in.

BTW, I'm not 100% happy with my naming of things (particularly UndefinedMethodDouble), so please make suggestions for anything you think could be organized or named better!

Apparently rspec/mocks cannot be used alone with Test::Unit

Rspec-mocks won't automatically extend its example methods once loaded, since it relies on an explicit RSpec::Mocks::setup(self) method, so that when RSpec is configured with other mocking frameworks, rspec-mocks won't have their extensions loaded (more information on http://github.com/rspec/rspec-mocks/issues/closed/#issue/7)

The thing is that RSpec::Mocks::setup(includer) includes its methods in includer's eigenclass, rather than its regular class (http://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks.rb#L181), so that the only way to include rspec-mocks as instance methods in Test::Unit::TestCases is to call the setup from inside an instance method of the test case itself:

class SomeTest < Test::Unit::TestCase
  def test_whatever
    RSpec::Mocks::setup(self)
    something.should_receive(:something_else) 
  end
end

This is not very comfortable. I've tried to force the setup to include its instance methods in the original Test::Unit::TestCase, with no luck. Any thoughts on how could this be achieved?

should_receive_in_child_process

I have been testing code that uses Process.fork. Specifically I'd like to test that a certain method is called when the parent process receives a signal. Obviously should_receive won't work because once I call Process.fork, the memory is no longer shared. It is possible to communicate with a named pipe or a temp file. Here is an example using a temp file.

      context "when it receives a SIGINT" do
        it "should call #stop! on its worker" do
          file = Tempfile.new("stop-stub-#{subject.worker.object_id}")

          # Make #stop! write out to a file so we can verify that it was called
          # even though it is run in a separate process.
          subject.worker.stub(:stop!) do |*args|
            msg = args.inspect
            file.puts msg
            Rails.logger.info "#stop! called on Worker with object_id; args: #{args.inspect}"
          end

          pid = Process.fork do
            subject.start!
          end
          sleep 0.1
          Process.kill('INT', pid)

          file.rewind
          lines = file.readlines
          lines.size.should == 1 # Called exactly once.
          lines[0].should == "[]\n" # Called with no arguments.
        end
      end

obviously it would be a lot nicer if I could do something like this:

      context "when it receives a SIGINT" do
        it "should call #stop! on its worker" do
          subject.worker.should_receive_in_child_process(:stop!)
          pid = Process.fork do
            subject.start!
          end
          sleep 0.1
          Process.kill('INT', pid)
        end
      end

Add a method on MockFrameworkAdapter to get the name of the currently used framework

I am writing some test helpers for a gem, so that users of the gem can easily stub out the gem behavior in the (controller) specs. In other words, somewhere in the example there would be something along the lines of
it "should do the right thing" do
stub_my_gem
get :my_action
result.should be_what_we_want
end

I would like to transparently be able to support all the mocking frameworks supported by RSpec, but in order to do that I would need to have all implementations of MockFrameworkAdapter to define a method name which would return the same symbol passed to +mock_with+ and allow my test helpers to create and setup the correct stubs for the given framework:
case RSpec.configuration.settings[:mock_framework].name
when :rr
stub_with_rr
when :rspec
stub_with_rspec
#and so forth
end
The change is fairly easy, and I could take care it, but before starting forking, patching etc... I would like to know whether I am on the right track or is there already an easier way to get the currently configured mock_framework.

shadowing warning

Perhaps this could be alleviated:

C:/installs/Ruby192/lib/ruby/gems/1.9.1/gems/rspec-mocks-2.6.0.rc2/lib/rspec/mocks/any_instance.rb:19: warning: shadowing outer local variable - instance

unstub fails with subclasses

If you unstub a parent class and then a child class, the child class will be given methods from the parent. e.g.

irb> require 'rspec'
irb> RSpec::Mocks::setup(Object.new)
irb> class Foo; end
irb> class Bar < Foo; end
irb> Foo.stub(:new)
irb> Bar.stub(:new)
irb> Foo.unstub(:new)
irb> Bar.unstub(:new)
irb> Bar.new
=> #<Foo:0x101ec4cd8>

any_instance doesn't work with `stub :name => :value`

I was playing with the new any_instance method and I noticed that it fails when using something like User.any_instance.stub :name => "John Doe".

The spec fails with this message:

Failure/Error: User.any_instance.stub :name => "John Doe"
 TypeError:
   {:name=>"John Doe"} is not a symbol

any_instance does not work when called inside of a before block

I have the following code which does not work. Version 2.6.0.

describe "foo" do
  before do
    Object.any_instance.stub(:foo).and_return(:return_value)
  end

  it "any_instance" do
    o = Object.new
    o.foo.should eq(:return_value)
  end    
end

before(:all) has the same outcome. I get:

Failures:

1) foo any_instance
Failure/Error: Object.any_instance.stub(:foo).and_return(:return_value)
NoMethodError:
undefined method `any_instance' for Object:Class

If I put the any_instance call inside of the it-block it is working as expected. Is it supposed to work? :-)

Support a "single.string" in stub_chain

thing.stub_chain("this.that.the_other").and_return("this value")

Seems more intention revealing than:

thing.stub_chain(:this, :that, :the_other).and_return("this value")

TypeError: RSpec::Mocks::Mock#to_hash should return Hash

controller

def create
  @city = City.new(params[:city])

  respond_with do |format|
    if @city.save
      format.html { redirect_to(admin_city_path(@city), :notice => 'City was successfully created.') }
    else
      format.html { render :action => "new" }
    end
  end
end

spec

def mock_city(stubs={})
  @mock_city ||= mock_model(City, stubs).as_null_object
end

describe "with valid params" do
  it "assigns a newly created city as @city" do
    City.stub(:new).with({'these' => 'params'}) { mock_city(:save => true) }
    post :create, :city => {'these' => 'params'}
    assigns(:city).should be(mock_city)
  end

  it "redirects to the created city" do
    City.stub(:new) { mock_city(:save => true) }
    post :create, :city => {}
    response.should redirect_to(city_url(mock_city))
  end
end

The problem seems to be with:
admin_city_path(@city)

Resulting in this error msg:
TypeError: RSpec::Mocks::Mock#to_hash should return Hash

Unhelpful error (ArgumentError: wrong number of arguments (1 for 0) when stubbing methods in classes that redefine public

Rspec has trouble stubbing methods whose classes redefine public. Presumably similar problems arise with other visibility modifying methods. Unfortunately, this makes testing, e.g. Sinatra apps, difficult.

Setup

# test.rb

#!/usr/bin/env ruby

require 'rubygems'
require 'rspec'

class MyClass
  def self.public; nil; end

  def foo; bar; end
  def bar; "bar"; end
end

describe MyClass do
  it "should do the right thing" do
    instance = MyClass.new
    instance.should_receive :bar
    instance.foo
  end
end

Actual Results

Rspec fails when attempting to stub :bar

$ rspec --version
2.5.1
$ rspec test.rb 
F

Failures:

  1) MyClass should do the right thing
     Failure/Error: def self.public; nil; end
     ArgumentError:
       wrong number of arguments (1 for 0)
     # ./test.rb:7:in `public'
     # ./test.rb:16:in `block (2 levels) in <top (required)>'

Finished in 0.00058 seconds
1 example, 1 failure

Expected Results

rspec should stub the method. The above test should pass.

Misleading report with argument constraints in message expectations

(Moved from https://github.com/rspec/rspec-expectations/issues#issue/42)

specify do
   @mymock = mock(:test)
   @mymock.should_receive(:test).with(1,2,3).once
   @mymock.should_receive(:test).with(3,2,1).once

   @mymock.test(1,2,3)
   @mymock.test(3,2,2)
 end

outputs:

Failures:
 1) TestTest test test
    Failure/Error: @mymock.test(3,2,2)
    Mock :test received :test with unexpected arguments
      expected: (1, 2, 3)
           got: (3, 2, 2)

Shouldn't it report:

expected: (3,2,1)
     got: (3,2,2)

Stubbing a method on any_instance twice causes that method to be undefined in later tests

I encountered a weird issue with 2.6.0.rc2 where I was stubbing a method on any_instance of a model. In the model specs (which were run after the controller specs) my tests were showing that the method was undefined.

from builds_controller_spec.rb:

before do
  Build.any_instance.stub(:already_built?).and_return(false)
end

it "should not create any builds when both builds already exist" do
  Build.any_instance.stub(:already_built?).and_return(true)
  post :create, :build => { :slot => 'something' }
  Build.count.should == 0
end

from build_spec.rb:

  it { should respond_to :already_built? }

If I run the controller spec first, I see this:

 Failure/Error: it { should respond_to :already_built? }
   expected #<Build id: nil ...> to respond to :already_built?

If I run the tests in the opposite order, everything is fine. I've narrowed the cause down to the specific any_instance line in the controller spec because if I comment out that one line, all of the other tests pass.

My assumption is that because I'm stubbing the same method on any_instance twice, it actually deletes the real method when cleaning up the 2nd time after the spec block.

Use __send__ method instead of send

Because some classes can override send method (for example TextMagic::API uses send method to send the sms through gateway, which makes it impossible to mock).

I will submit pull request soon.

File.stub(:exist?).with(x) causes NoMethodError when File.exist?(y) is called

I'm specing some behavior that depends on the existence or absence of a file. I'm doing so with a stub:

context 'when the file exists' do
  before(:each) { File.stub(:exist?).with(file_name).and_return(true) }

  it "returns :bar from #foo" do
    described_class.new(file_name).foo.should == :bar
  end
end

This works fine except that described_class's initializer also calls File.exist? with a different argument. That causes an error: NoMethodError: undefined method 'exist?' for IO:Class.

It seems to me that an argument-limited stub of an existing method should delegate to the original method definition when the method is called with a different argument, rather than raising a NoMethodError. My stubbing of File.exist? for file x should not effect File.exist?(y).

Using `any_instance` mocking propagates accross contexts.

Hi If i have two tests like this:

it "should call the method" do
   SomeClass.any_instance.expects(:the_method)
   @my_test_object.a_method_that_calls_the_method
end

it "should reset the authenticator application data" do
   @my_test_object.a_method_that_calls_the_method
   @my_test_object.some_property.should == "something else"
 end

So in short: two test-blocks, where in the first i check if the method is actually called, and in the second i check for the effects of the complete method --including the previously stubbed method.

What happens then: in the second test the actual method is not called, by I get the error that the expectation was received again. So somehow, the any_instance sticks between tests, and I would expect it to last for only the current scope (test/context/ ...).

Is this the intended behaviour?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.