pax_global_header00006660000000000000000000000064126347655070014531gustar00rootroot0000000000000052 comment=afb9a0fbaeac82a757b66652476040132da58daa flexmock-2.0.4/000077500000000000000000000000001263476550700133445ustar00rootroot00000000000000flexmock-2.0.4/.autotest000066400000000000000000000002671263476550700152220ustar00rootroot00000000000000Autotest.add_hook :run do |at| at.exceptions = /^(?:.\/)?(?:db|doc|log|public|script|sphinx|tmp|filestore|vendor\/rails)|\.svn|test_unit_integration|(?:.*_flymake\.rb$|\.log$)/ end flexmock-2.0.4/.gitignore000066400000000000000000000001621263476550700153330ustar00rootroot00000000000000*~ *.bak pkg .DS_Store coverage html TAGS doc/examples/*.rdoc Gemfile.lock vendor/ .*.sw? .yardoc/ .bundle/ html/ flexmock-2.0.4/.togglerc000066400000000000000000000002471263476550700151560ustar00rootroot00000000000000(add-to-list 'toggle-mapping-styles '(flexmock ("test/\\1_test.rb" . "lib/flexmock/\\1.rb") ("\\1_test.rb" . "\\1.rb"))) (buffer-toggle-style 'flexmock) flexmock-2.0.4/.travis.yml000066400000000000000000000000621263476550700154530ustar00rootroot00000000000000language: ruby rvm: - 2.0.0 - 2.1.6 - 2.2.2 flexmock-2.0.4/.yardopts000066400000000000000000000000521263476550700152070ustar00rootroot00000000000000--output-dir html --readme doc/index.rdoc flexmock-2.0.4/CHANGES000066400000000000000000000154671263476550700143540ustar00rootroot00000000000000= Changes for FlexMock == Version 2.0.0 * bump to 2.0 to mark the change of maintainership. I hope I won't disappoint. * require 'flexmock' no longer pulls test_unit_integration. Require the latter explicitely * dropped support for pre-2.0 Rubies * added explicit minitest support. This makes the minitest integration much nicer to work with (in particular, the flexmock_teardown is now executed "just at the right place"), and fixes issues with minitest 5. Just require flexmock/minitest to get it. * partial mocks now supports prepended modules * validation errors that happen when a method is called (i.e. unexpected arguments, wrong call count) are reported with the backtrace of the call instead of with the backtrace of the expectation definition. == Version 1.0.0 * Added spy support. * Added base class mocking restrictions. * Using singleton_methods to get list of singleton methods (rather than methods(false)) * Correctly handling mocking methods that were meta-programmed with method_missing. == Version 0.9.0 * Ruby 1.9.3 compatibility changes. == Version 0.8.5 * Fixed warning about a void context. * hsh() argument matcher now reports its matching constraints in error messages. == Version 0.8.4 * Added support for rails 2.2.x in should_render_view. == Version 0.8.3 * Fixed a bug where the by_default option was not completely honored in some edge cases. == Version 0.8.2 * Added workaround for compatibility issues with RSpec on Rails. == Version 0.8.1 * Additional fix for Rails 2.0.2 * Added Joe O'Brien's patch to allow view stubbing in Rails 2.0 * Added Evan Phoenix's patch to remove allocate from default allocators in new_instances (for Rubinius compatibility). == Version 0.8.0 * Added by_default * Added undefined behavior * Mock methods are added to partial mocks only if they are not previously defined. This should reduce the need for safe mode. * respond_to? on mocks now accepts multiple arguments. This eases mocking in rails a little bit. * Added experimental view mocking for rails. == Version 0.7.2 * Changed initial model Id to 10000. * Added test suggested for RSpec Mocks, just to make sure we were good too. == Version 0.7.1 * Updated install.rb to handle non-root destination directories via DESTDIR. * Fixed operator bug introduced in 0.7.0. == Version 0.7.0 * Added +and_yield+ as an expectation clause. * Inspect on Mocks now yield a more consise description. * Global ordering across all mocks in a container is now allowed. * Added support for Demeter chain mocking. * Deprecated a number of mock_* methods. == Version 0.6.4 * Renamed flexmodel(...) to flexmock(:model, ...) because visually they were too similar. == Version 0.6.3 * Added flexmodel() for better support of mocking ActiveRecord models. * Fixed comment for singleton? * Fixed coverage report for the partial mocking class. * Fixed bug when partial mock objects reported they respond to a method but they actually didn't. * The flexmock() method now _always_ returns a combination domain/mock object. For partial mocks, this implies that the domain object now has mock support methods on it (e.g. should_receive). * Safe mode for partials was introduced for the small number of cases where mock support methods in the domain object would cause problems. * Internally renamed PartialMock to PartialMockProxy. == Version 0.6.2 * flexmock() with a block now always returns the domain object. flexmock() without a block returns the mock object. Note that for normal mocks, the domain and mock objects are the same. For partial mocks, the mock is separate from the domain object. * Added +and_raise+ to the list of expection specifications. == Version 0.6.1 * Fixed bug that prevented mocks from mocking field assignment operators. * Fixed bug that prevented partial mocks from being ordered. == Version 0.6.0 * Dropped class interception. * Refactored into more granular classes. * Added RSpec integration. * Added hash expectations to flexmock() and should_expect(). * Integrated partial mocks into the flexmock() methods. * Allow non-block configuration of new_instances. == Version 0.5.1 * Changed the name of any_instance to new_instances. Deprecated any_instance. * Added ability to stub any class method in new_instances. * Added RCov task * Reworked original behavior hooks to use method aliasing rather than method procs. * Fixed bug in stubbing File class methods. == Version 0.5.0 * Added any_instance stubbing to class objects. == Version 0.4.5 * Fixed version typo in 0.4.4 (internally claimed to be 0.4.3.1) == Version 0.4.4 * Added block support to flexstub. == Version 0.4.3 * Fixed bug where non-direct class methods were not properly handled. == Version 0.4.2 * Fixed bug where multiple stubs of a class method were not properly restored. == Version 0.4.1 * Removed include of Test::Unit::Assertions from Expectations. * Fixed mocking of kernel methods. == Version 0.4.0 * Added stubbing for mocking methods of existing objects. * Added multiple return values for the +and_returns+ method. * Added block initialization to the flexmock method. == Version 0.3.2 * Fixed bug when mock is used as a replacement class in class interception. == Version 0.3.1 * Fixed some warnings regarding uninitialized variables. * Added (very) simple class interception. * Added the mock_factory method to go along with class interception. * When using Test::Unit integration, avoid mock verification if the test has already failed for some reason. == Version 0.3.0 * Added Test::Unit integration. == Version 0.2.1 * Added strict mode in record mode interface to facility using known good algorithms for comparison testing. * Improved the docs and examples. Fixed garbled first example in README. == Version 0.2.0 * Added record mode for building expectations. * Fixed a bunch of documentation. == Version 0.1.7 * Bumped version because 0.1.6 was uploaded to the wrong Rubyforge area. == Version 0.1.6 * Added a proc based matcher for arguments (using keyword +on+). == Version 0.1.5 * Fixed the overzealous argument matching when String is given as an argument qualifier to +should_receive+. == Version 0.1.4 * Added eq and any methods for argument matching. * Added tests for the "first match" argument matching policy. == Version 0.1.3 * Improved the definition of ordered so that it takes group names instead of explicit order numbers. This make the code easier to write and the API easier to understand. == Version 0.1.2 * Fixed homepage in gem spec. * Removed autorequire from gemspec. * Fixed README to be automatically updated with FlexMock Version == Version 0.1.1 * Added responds_to? and method support. * Added JMock style expectations. == Version 0.0.3 * Changed to a GEM package. == Version 0.0.2 * Updated the documentation. * Fixed the install script. == Version 0.0.1 * Initial Version flexmock-2.0.4/Gemfile000066400000000000000000000000471263476550700146400ustar00rootroot00000000000000source 'http://rubygems.org' gemspec flexmock-2.0.4/README.md000066400000000000000000001165731263476550700146400ustar00rootroot00000000000000# Flex Mock -- Making Mocking Easy [![Build Status](https://travis-ci.org/doudou/flexmock.svg?branch=master)](https://travis-ci.org/doudou/flexmock) [![Gem Version](https://badge.fury.io/rb/flexmock.svg)](http://badge.fury.io/rb/flexmock) [![Coverage Status](https://coveralls.io/repos/doudou/flexmock/badge.svg?branch=master&service=github)](https://coveralls.io/github/doudou/flexmock?branch=master) [![Documentation](http://b.repl.ca/v1/yard-docs-blue.png)](http://rubydoc.info/gems/flexmock/frames) FlexMock is a simple, but flexible, mock object library for Ruby unit testing. ## Installation You can install FlexMock with the following command. ``` $ gem install flexmock ``` ## Simple Example We have a data acquisition class (TemperatureSampler) that reads a temperature sensor and returns an average of 3 readings. We don't have a _real_ temperature to use for testing, so we mock one up with a mock object that responds to the `read_temperature` message. Here's the complete example: ```ruby require 'test/unit' require 'flexmock/test_unit' class TemperatureSampler def initialize(sensor) @sensor = sensor end def average_temp total = (0...3).collect { @sensor.read_temperature }.inject { |i, s| i + s } total / 3.0 end end class TestTemperatureSampler < Test::Unit::TestCase def test_sensor_can_average_three_temperature_readings sensor = flexmock("temp") sensor.should_receive(:read_temperature).times(3). and_return(10, 12, 14) sampler = TemperatureSampler.new(sensor) assert_equal 12, sampler.average_temp end end ``` You can find an extended example of FlexMock in [Google Example](http://flexmock.rubyforge.org/files/doc/GoogleExample_rdoc.html "Example"). ## Minitest Integration FlexMock integrates nicely with Minitest. Just require the 'flexmock/minitest' file at the top of your test file. The `flexmock` method will be available for mock creation, and any created mocks will be automatically validated and closed at the end of the individual test. It works with both tests unit-style (subclasses of Minitest::Test) and spec-style. Your test case will look something like this: ```ruby require 'flexmock/minitest' class TestDog < Minitest::Test def test_dog_wags tail_mock = flexmock(:wag => :happy) assert_equal :happy, tail_mock.wag end end ``` **NOTE:** If you don't want to automatically extend every Minitest::Test with the flexmock methods and overhead, then require the 'flexmock' file and explicitly include the FlexMock::Minitest module in each test case class where you wish to use mock objects. ## Test::Unit Integration FlexMock integrates nicely with Test::Unit. Just require the 'flexmock/test_unit' file at the top of your test file. The `flexmock` method will be available for mock creation, and any created mocks will be automatically validated and closed at the end of the individual test. Your test case will look something like this: ```ruby require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags tail_mock = flexmock(:wag => :happy) assert_equal :happy, tail_mock.wag end end ``` **NOTE:** If you don't want to automatically extend every TestCase with the flexmock methods and overhead, then require the 'flexmock' file and explicitly include the FlexMock::TestCase module in each test case class where you wish to use mock objects. FlexMock versions prior to 0.6.0 required the explicit include. ## RSpec Integration FlexMock also supports integration with the RSpec behavior specification framework. Starting with version 0.9.0 of RSpec, you will be able to say: ```ruby RSpec.configure do |config| config.mock_with :flexmock end describe "Using FlexMock with RSpec" do it "should be able to create a mock" do m = flexmock(:foo => :bar) m.foo.should === :bar end end ``` **NOTE:** _I often can't remember the proper RSpec configuration for flexmock without looking it up. If you are the same, you can put require 'flexmock/rspec/configure' in your spec helper to auto-configure RSpec to use flexmock._ **NOTE:** _Older versions of RSpec used the Spec::Runner for configuration. If you are running with a very old RSpec, you may need the following:_ ```ruby # Configuration for RSpec prior to RSpec 2.x Spec::Runner.configure do |config| config.mock_with :flexmock end ``` ## Quick Reference ### Creating Mock Objects The `flexmock` method is used to create mocks in various configurations. Here's a quick rundown of the most common options. See FlexMock::MockContainer#flexmock for more details. * mock = flexmock("joe") Create a mock object named "joe" (the name is used in reporting errors). * mock = flexmock(:foo => :bar, :baz => :froz) Create a mock object and define two mocked methods (:foo and :baz) that return the values :bar and :froz respectively. This is useful when creating mock objects with just a few methods and simple return values. * mock = flexmock("joe", :foo => :bar, :bar => :froz) You can combine the mock name and an expectation hash in the same call to flexmock. * mock = flexmock("joe", :on, User) This defines a strict mock that is based on the User class. Strict mocks prevent you from mocking or stubbing methods that are not instance methods of the restricting class (i.e. User in our example). This helps prevent tests from becoming stale with incorrectly mocked objects when the method names change. Use the `explicitly` modifier to `should_receive` to override the strict mock restrictions. * partial_mock = flexmock(real_object) If you you give `flexmock` a real object in the argument list, it will treat that real object as a base for a partial mock object. The return value `partial_mock` may be used to set expectations. The real_object should be used in the reference portion of the test. * partial_mock = flexmock(real_object, :on, class_object) * partial_mock = flexmock(real_object, :strict) Partial mocks can also take a restricting base, so that you cannot mock methods not in the class (without the explicitly modifier). Since partials already have a class, you can use the :strict keyword to mean the same thing as :on, real_object.class. * partial_mock = flexmock(real_object, "name", :foo => :baz) Names and expectation hashes may be used with partial mocks as well. * partial_mock = flexmock(:base, real_string_object) Since Strings (and Symbols for that matter) are used for mock names, FlexMock will not recognize them as the base for a partial mock. To force a string to be used as a partial mock base, proceed the string object in the calling sequence with :base. * partial_mock = flexmock(:safe, real_object) { |mock| mock.should_receive(...) } When mocking real objects (i.e. "partial mocks"), FlexMock will add a handful of mock related methods to the actual object (see below for list of method names). If one or more of these added methods collide with an existing method on the partial mock, then there are problems. FlexMock offers a "safe" mode for partial mocks that does not add these methods. Indicate safe mode by passing the symbol :safe as the first argument of flexmock. A block _is required_ when using safe mode (the partial_mock returned in safe mode does not have a `should_receive` method). The methods added to partial mocks in non-safe mode are: * should_receive * new_instances * flexmock_get * flexmock_teardown * flexmock_verify * flexmock_received? * flexmock_calls * mock = flexmock(...) { |mock| mock.should_receive(...) } If a block is given to any of the `flexmock` forms, the mock object will be passed to the block as an argument. Code in the block can set the desired expectations for the mock object. * mock_model = flexmock(:model, YourModel, ...) { |mock| mock.should_receive(...) } When given `:model`, `flexmock()` will return a pure mock (not a partial mock) that will have some ActiveRecord specific methods defined. YourModel should be the class of an ActiveRecord model. These predefined methods make it a bit easier to mock out ActiveRecord model objects in a Rails application. Other that the predefined mocked methods, the mock returned is a standard FlexMock mock object. The predefined mocked methods are: * id -- returns a unique ID for each mocked model. * to_params -- returns a stringified version of the id. * new_record? -- returns false. * errors -- returns an empty (mocked) errors object. * is_a?(other) -- returns true if other == YourModel. * instance_of?(class) -- returns true if class == YourModel * kind_of?(class) -- returns true if class is YourModel or one of its ancestors * class -- returns YourModel. * mock = flexmock(... :on, class_object, ...) **NOTE:** Versions of FlexMock prior to 0.6.0 used `flexstub` to create partial mocks. The `flexmock` method now assumes all the functionality that was spread out between two different methods. `flexstub` is deprecated, but still available for backward compatibility. ### Expectation Declarators Once a mock is created, you need to define what that mock should expect to see. Expectation declarators are used to specify these expectations placed upon received method calls. A basic expectation, created with the `should_receive` method, just establishes the fact that a method may (or may not) be called on the mock object. Refinements to that expectation may be additionally declared. FlexMock always starts with the most general expectation and adds constraints to that. For example, the following code: ```ruby mock.should_receive(:average).and_return(12) ``` Means that the mock will now accept method calls to an `average` method. The expectation will accept any arguments and may be called any number of times (including zero times). Strictly speaking, the `and_return` part of the declaration isn't exactly a constraint, but it does specify what value the mock will return when the expectation is matched. If you want to be more specific, you need to add additional constraints to your expectation. Here are some examples: ```ruby mock.should_receive(:average).with(12).once mock.should_receive(:average).with(Integer). at_least.twice.at_most.times(10). and_return { rand } ``` Expectation are always matched in order of declaration. That means if you have a general expectation before a more specific expectation, the general expectation will have an opportunity to match first, effectively hiding the second expectation. For example: ```ruby mock.should_receive(:average) # Matches any call to average mock.should_receive(:average).with(1).once # Fails because it never matches ``` In the example, the second expectation will never be triggered because all calls to average will be handled by the first expectation. Since the second expectation is require to match one time, this test will fail. Reversing the order of the expections so that the more specific expectation comes first will fix that problem. If an expectation has a count requirement (e.g. `once` or `times`), then once it has matched its expected number of times, it will let other expectations have a chance to match. For example: ```ruby mock.should_receive(:average).once.and_return(1) mock.should_receive(:average).once.and_return(2) mock.should_receive(:average).and_return(3) ``` In the example, the first time average is called, the first expectation is matched an average will return 1. The second time average is called, the second expectation matches and 2 is returned. For all calls to average after that, the third expectation returning 3 will be used. Occasionally it is useful define a set of expecations in a setup method of a test and override those expectations in specific tests. If you mark an expectation with the `by_default` marker, that expectation will be used only if there are no non-default expectations on that method name. See "by_default" below. ### Expectation Criteria The following methods may be used to create and refine expectations on a mock object. See theFlexMock::Expectation for more details. * should_receive(method_name) Declares that a message named _method_name_ will be sent to the mock object. Constraints on this expected message (called expectations) may be chained to the `should_receive` call. * should_receive(method_name1, method_name2, ...) Define a number of expected messages that have the same constraints. * should_receive(meth1 => result1, meth2 => result2, ...) Define a number of expected messages that have the same constrants, but return different values. * should_receive(...).explicitly If a mock has a base class, use the `explicitly` modifier to override the restriction on method names imposed by the base class. The `explicitly` modifier must come immediately after the `should_receive` call and before any other expectation declarators. If a mock does not have a base class, this method has no effect. * should_expect { |recorder| ... } Creates a mock recording object that will translate received method calls into mock expectations. The recorder is passed to a block supplied with the `should_expect` method. See examples below. * with(arglist) Declares that this expectation matches messages that match the given argument list. The `===` operator is used on a argument by argument basis to determine matching. This means that most literal values match literally, class values match any instance of a class and regular expression match any matching string (after a `to_s` conversion). See argument validators (below) for details on argument validation options. * with_any_args Declares that this expectation matches the message with any argument (default) * with_no_args Declares that this expectation matches messages with no arguments * zero_or_more_times Declares that the expected message is may be sent zero or more times (default, equivalent to `at_least.never`). * once Declares that the expected message is only sent once. `at_least` / `at_most` modifiers are allowed. * twice Declares that the expected message is only sent twice. `at_least` / `at_most` modifiers are allowed. * never Declares that the expected message is never sent. `at_least` / `at_most` modifiers are allowed. * times(n) Declares that the expected message is sent _n_ times. `at_least` / `at_most` modifiers are allowed. * at_least Modifies the immediately following message count constraint so that it means the message is sent at least that number of times. E.g. `at_least.once` means the message is sent at least once during the test, but may be sent more often. Both `at_least` and `at_most` may be specified on the same expectation. * at_most Similar to `at_least`, but puts an upper limit on the number of messages. Both `at_least` and `at_most` may be specified on the same expectation. * ordered Declares that the expected message is ordered and is expected to be received in a certain position in a sequence of messages. The message should arrive after and previously declared ordered messages and prior to any following declared ordered messages. Unordered messages are ignored when considering the message order. Normally ordering is performed only against calls in the same mock object. If the "globally" adjective is used, then ordering is performed against the other globally ordered method calls. * ordered(group) Declare that the expected message belongs to an order group. Methods within an order group may be received in any order. Ordered messages outside the group must be received either before or after all of the grouped messages. For example, in the following, messages `flip` and `flop` may be received in any order (because they are in the same group), but must occur strictly after `start` but before `end`. The message `any_time` may be received at any time because it is not ordered. ```ruby m = flexmock() m.should_receive(:any_time) m.should_receive(:start).ordered m.should_receive(:flip).ordered(:flip_flop_group) m.should_receive(:flop).ordered(:flip_flop_group) m.should_receive(:end).ordered ``` Normally ordering is performed only against calls in the same mock object. If the "globally" adjective is used, then ordering is performed against the other globally ordered method calls. * globally.ordered * globally.ordered(group_name) When modified by the "globally" adjective, the mock call will be ordered against other globally ordered methods in any of the mock objects in the same container (i.e. same test). All the options of the per-mock ordering are available in the globally ordered method calls. * by_default Marks the expectation as a default. Default expectations act as normal as long as there are no non-default expectations for the same method name. As soon as a non-default expectation is defined, all default expectations for that method name are ignored. Default expectations allow you to setup a set of default behaviors for various methods in the setup of a test suite, and then override only the methods that need special handling in any given test. ### Expectation Actions Action expectations are used to specify what the mock should _do_ when the expectation is matched. The actions themselves do not take part in determining whether a given expectation matches or not. * and_return(value) Declares that the expected message will return the given value. * and_return(value1, value2, ...) Declares that the expected message will return a series of values. Each invocation of the message will return the next value in the series. The last value will be repeatably returned if the number of matching calls exceeds the number of values. * and_return { |args, ...| code ... } Declares that the expected message will return the yielded value of the block. The block will receive all the arguments in the message. If the message was provided a block, it will be passed as the last parameter of the block's argument list. * returns( ... ) Alias for `and_return`. * and_return_undefined Declares that the expected message will return a self-preserving undefined object (see FlexMock::Undefined for details). * returns_undefined Alias for `and_returns_undefined` * and_raise(_exception_, _*args_) Declares that the expected message will raise the specified exception. If `exception` is an exception class, then the raised exception will be constructed from the class with `new` given the supplied arguments. If `exception` is an instance of an exception class, then it will be raised directly. * raises( ... ) Alias for `and_raise`. * and_throw(symbol) * and_throw(symbol, value) Declares that the expected messsage will throw the specified symbol. If an optional value is included, then it will be the value returned from the corresponding catch statement. * throws( ... ) Alias for `and_throw`. * and_yield(values, ...) Declares that the mocked method will receive a block, and the mock will call that block with the values given. Not providing a block will be an error. Providing more than one `and_yield` clause one a single expectation will mean that subsquent mock method calls will yield the values provided by the additional `and_yield` clause. * yields( ... ) Alias for `and_yield( ... )`. * pass_thru * pass_thru { |value| .... } Declares that the expected message will allow the method to be passed to the original method definition in the partial mock object. `pass_thru` is also allowed on regular mocks, but since there is no original method to be called, pass_thru will always return the undefined object. If a block is supplied to `pass_thru`, the value returned from the original method will be passed to the block and the value of the block will be returned. This allows you to mock methods on the returned value. ```ruby Dog.should_receive(:new).pass_thru { |dog| flexmock(dog, :wag => true) } ``` ### Other Expectation Methods * mock Expectation constraints always return the expectation so that the constraints can be chained. If you wish to do a one-liner and assign the mock to a variable, the `mock` method on an expectation will return the original mock object. ```ruby m = flexmock.should_receive(:hello).once.and_return("World").mock ``` **NOTE:** _Using **mock** when specifying a Demeter mock chain will return the last mock of the chain, which might not be what you expect._ ### Argument Validation The values passed to the `with` declarator determine the criteria for matching expectations. The first expectation found that matches the arguments in a mock method call will be used to validate that mock method call. The following rules are used for argument matching: * A `with` parameter that is a class object will match any actual argument that is an instance of that class. Examples: ```ruby with(Integer) will match f(3) ``` * A regular expression will match any actual argument that matches the regular expression. Non-string actual arguments are converted to strings via `to_s` before applying the regular expression. Examples: ```ruby with(/^src/) will match f("src_object") with(/^3\./) will match f(3.1415972) ``` * Most other objects will match based on equal values. Examples: ```ruby with(3) will match f(3) with("hello") will match f("hello") ``` * If you wish to override the default matching behavior and force matching by equality, you can use the FlexMock.eq convenience method. This is mostly used when you wish to match class objects, since the default matching behavior for class objects is to match instances, not themselves. Examples: ```ruby with(eq(Integer)) will match f(Integer) with(eq(Integer)) will NOT match f(3) ``` **Note:** If you do not use the FlexMock::TestCase Test Unit integration module, or the FlexMock::ArgumentTypes module, you will have to fully qualify the `eq` method. This is true of all the special argument matches (`eq`, `on`, `any`, `hsh` and `ducktype`). ```ruby with(FlexMock.eq(Integer)) with(FlexMock.on { code }) with(FlexMock.any) with(FlexMock.hsh(:tag => 3)) with(FlexMock.ducktype(:wag, :bark)) ``` * If you wish to match a hash on _some_ of its values, the `FlexMock.hsh(...)` method will work. Only specify the hash values you are interested in, the others will be ignored. ```ruby with(hsh(:run => true)) will match f(:run => true, :stop => false) ``` * If you wish to match any object that responds to a certain set of methods, use the `FlexMock.ducktype` method. ```ruby with(ducktype(:to_str)) will match f("string") with(ducktype(:wag, :bark)) will match f(dog) (assuming dog implements wag and bark) ``` * If you wish to match _anything_, then use the `FlexMock.any` method in the with argument list. Examples (assumes either the FlexMock::TestCase or FlexMock::ArgumentTypes mix-ins has been included): ```ruby with(any) will match f(3) with(any) will match f("hello") with(any) will match f(Integer) with(any) will match f(nil) ``` * If you wish to specify a complex matching criteria, use the `FlexMock.on(&block)` with the logic contained in the block. Examples (assumes `FlexMock::ArgumentTypes` has been included): ```ruby with(on { |arg| (arg % 2) == 0 } ) ``` will match any even integer. * If you wish to match a method call where a block is given, add `Proc` as the last argument to `with`. Example: ```ruby m.should_receive(:foo).with(Integer,Proc).and_return(:got_block) m.should_receive(:foo).with(Integer).and_return(:no_block) ``` will cause the mock to return the following: ```ruby m.foo(1) { } => returns :got_block m.foo(1) => returns :no_block ``` ### Creating Partial Mocks Sometimes it is useful to mock the behavior of one or two methods in an existing object without changing the behavior of the rest of the object. If you pass a real object to the `flexmock` method, it will allow you to use that real object in your test and will just mock out the one or two methods that you specify. For example, suppose that a Dog object uses a Woofer object to bark. The code for Dog looks like this (we will leave the code for Woofer to your imagination): ```ruby class Dog def initialize @woofer = Woofer.new end def bark @woofer.woof end def wag :happy end end ``` Now we want to test Dog, but using a real Woofer object in the test is a real pain (why? ... well because Woofer plays a sound file of a dog barking, and that's really annoying during testing). So, how can we create a Dog object with mocked Woofer? All we need to do is allow FlexMock to replace the `bark` method. Here's the test code: ```ruby class TestDogBarking < Test::Unit::TestCase include FlexMock::TestCase # Setup the tests by mocking the +new+ method of # Woofer and return a mock woofer. def setup @dog = Dog.new flexmock(@dog, :bark => :grrr) end def test_dog assert_equal :grrr, @dog.bark # Mocked Method assert_equal :happy, @dog.wag # Normal Method end end ``` The nice thing about this technique is that after the test is over, the mocked out methods are returned to their normal state. Outside the test everything is back to normal. **NOTE:** In previous versions of FlexMock, partial mocking was called "stubs" and the `flexstub` method was used to create the partial mocks. Although partial mocks were often used as stubs, the terminology was not quite correct. The current version of FlexMock uses the `flexmock` method to create both regular stubs and partial stubs. A version of the `flexstub` method is included for backwards compatibility. See Martin Fowler's article [_Mocks Aren't Stubs_](http://www.martinfowler.com/articles/mocksArentStubs.html "Mocks Aren't Stubs") for a better understanding of the difference between mocks and stubs. This partial mocking technique was inspired by the `Stuba` library in the `Mocha` project. ### Spies FlexMock supports spy-like mocks as well as the traditional mocks. ```ruby # In Test::Unit / MiniTest class TestDogBarking < Test::Unit::TestCase def test_dog dog = flexmock(:on, Dog) dog.bark("loud") assert_spy_called dog, :bark, "loud" end end # In RSpec describe Dog do let(:dog) { flexmock(:on, Dog) } it "barks loudly" do dog.bark("loud") dog.should have_received(:bark).with("loud") end end ``` Since spies are verified after the code under test is run, they fit very nicely with the Given/When/Then technique of specification. Here is the above RSpec example using the rspec-given gem: ```ruby require 'rspec/given' describe Dog do Given(:dog) { flexmock(:on, Dog) } context "when barking loudly" do When { dog.bark("loud") } Then { dog.should have_received(:bark).with("loud") } end end ``` *NOTE:* You can only spy on methods that are mocked or stubbed. That's not a problem with regular mocks, but normal methods on partial objects will not be recorded. You can get around this limitation by stubbing the method in question on the normal mock, and then specifying `pass_thru`. Assuming `:bark` is a normal method on a Dog object, then the following allows for spying on `:bark`. ```ruby dog = Dog.new flexmock(dog).should_receive(:bark).pass_thru # ... dog.should have_received(:bark) ``` #### Asserting Spy Methods are Called (Test::Unit / MiniTest) FlexMock provied a custom assertion method for use with Test::Unit and MiniTest for asserting that mocked methods are actually called. * assert_spy_called mock, options_hash, method_name, args... This will assert that the method called _method_name_ has been called at least once on the given mock object. If arguments are given, then the method must be called with actual argument that match the given argument matchers. All the argument matchers defined in the "Argument Validation" section above are allowed in the `assert_spy_called` method. The `options` hash is optional. If omitted, all options will have their default values. See below for spy option definitions. * assert_spy_not_called mock, options_hash, method_name, args... Same as `assert_spy_called`, except with the sense of the test reversed. *Spy Options* * times: n Specify the number of times a matching method should have been invoked. `nil` (or omitted) means any number of times. * with_block: true/false/nil Is a block required on the invocation? `true` means the method must be invoked with a block. `false` means the method must have been invoked without a block. `nil` means that the presence of a block does not matter. Default is `nil`. * and: [proc1, proc2...] Additional validations to be run on each matching method call. The list of arguments for each call is passed to the procs. This allows additional validations on supplied arguments. Default is no additional validations. * on: n Only apply the additional validations on the n'th invocation of the matching method. Default is apply additional validations to all invocations. *Examples:* ```ruby dog = flexmock(:on, Dog) dog.wag(:tail) dog.wag(:head) dog.bark(5) dog.bark(6) assert_spy_called dog, :wag, :tail assert_spy_called dog, :wag, :head assert_spy_called dog, {times: 2}, :wag assert_spy_not_called dog, :bark assert_spy_not_called dog, {times: 3}, :wag is_even = proc { |n| assert_equal 0, n%2 } assert_spy_called dog, { and: is_even, on: 2 }, :bark, Integer ``` #### RSpec Matcher for Spying FlexMock also provides an RSpec matcher that can be used to specify spy behavior. * mock.should have_received(method_name).modifier1.modifier2... Specifies that the method named _method_name_ should have been received by the mock object with the given arguments. Just like `should_receive`, `have_received` will accept a number of modifiers that modify its behavior. *Modifiers for `have_received`* * with(args) If a `with` modifier is given, only messages with matching arguments are considered. _args_ can be any of the argument matches mentioned in the "Argument Validation" section above. If `with` is not given, then the arguments are not considered when finding matching calls. * times(n) If a `times` modifier is given, then there must be exactly `n` calls for that method name on the mock. If the `times` clause is not given, then there must be at least one call matching the method name (and arguments if they are considered). * `never` is an alias for `times(0)`, * `once` is an alias for `times(1)`, and * `twice` is an alias for `times(2)`. * and { |args| code } If an `and` modifier is given, then the supplied block will be run as additional validations on any matching call. Arguments to the matching call will be supplied to the block. If multiple `and` modifiers are given, all the blocks will be run. The additional validations are run on all the matching calls unless an `on` modifier is supplied. * on(n) If an `on` modifier is given, then the additional validations supplied by `and` will only be run on the n'th invocation of the matching method. *Examples:* ```ruby dog = flexmock(:on, Dog) dog.wag(:tail) dog.wag(:head) dog.should have_received(:wag).with(:tail) dog.should have_received(:wag).with(:head) dog.should have_received(:wag).twice dog.should_not have_received(:bark) dog.should_not have_received(:wag).times(3) dog.bark(3) dog.bark(6) dog.should have_received(:bark).with(Integer).and { |arg| (arg % 3).should == 0 } dog.should have_received(:bark).with(Integer).and { |arg| arg.should == 6 }.on(2) ``` ### Mocking Class Object In the previous example we mocked out the `bark` method of a Dog object to avoid invoking the Woofer object. Perhaps a better technique would be to mock the Woofer object directly. But Dog uses Woofer explicitly so we cannot just pass in a mock object for Dog to use. But wait, we can add mock behavior to any existing object, and classes are objects in Ruby. So why don't we just mock out the Woofer class object to return mocks for us. ```ruby class TestDogBarking < Test::Unit::TestCase include FlexMock::TestCase # Setup the tests by mocking the `new` method of # Woofer and return a mock woofer. def setup flexmock(Woofer).should_receive(:new). and_return(flexmock(:woof => :grrr)) @dog = Dog.new end def test_dog assert_equal :grrrr, @dog.bark # Calls woof on mock object # returned by Woofer.new end end ``` ### Mocking Behavior in All Instances Created by a Class Object Sometimes returning a single mock object is not enough. Occasionally you want to mock _every_ instance object created by a class. FlexMock makes this very easy. ```ruby class TestDogBarking < Test::Unit::TestCase include FlexMock::TestCase # Setup the tests by mocking Woofer to always # return partial mocks. def setup flexmock(Woofer).new_instances.should_receive(:woof => :grrr) end def test_dog assert_equal :grrrr, Dog.new.bark # All dog objects assert_equal :grrrr, Dog.new.bark # are mocked. end end ``` Note that FlexMock adds the mock expectations after the original `new` method has completed. If the original version of `new` yields the newly created instance to a block, that block will get an non-mocked version of the object. Note that `new_instances` will accept a block if you wish to mock several methods at the same time. E.g. ```ruby flexmock(Woofer).new_instances do |m| m.should_receive(:woof).twice.and_return(:grrr) m.should_receive(:wag).at_least.once.and_return(:happy) end ``` ### Default Expectations on Mocks Sometimes you want to setup a bunch of default expectations that are pretty much for a number of different tests. Then in the individual tests, you would like to override the default behavior on just that one method you are testing at the moment. You can do that by using the `by_default` modifier. In your test setup you might have: ```ruby def setup @mock_dog = flexmock("Fido") @mock_dog.should_receive(:tail => :a_tail, :bark => "woof").by_default end ``` The behaviors for `:tail` and `:bark` are good for most of the tests, but perhaps you wish to verify that `:bark` is called exactly once in a given test. Since :bark by default has no count expectations, you can override the default in the given test. ```ruby def test_something_where_bark_must_be_called_once @mock_dog.should_receive(:bark => "woof").once # At this point, the default for :bark is ignored, # and the "woof" value will be returned. # However, the default for :tail (which returns :a_tail) # is still active. end ``` By setting defaults, your individual tests don't have to concern themselves with details of all the default setup. But the details of the overrides are right there in the body of the test. ### Mocking Law of Demeter Violations The Law of Demeter says that you should only invoke methods on objects to which you have a direct connection, e.g. parameters, instance variables, and local variables. You can usually detect Law of Demeter violations by the excessive number of periods in an expression. For example: ```ruby car.chassis.axle.universal_joint.cog.turn ``` The Law of Demeter has a very big impact on mocking. If you need to mock the "turn" method on "cog", you first have to mock chassis, axle, and universal_joint. ```ruby # Manually mocking a Law of Demeter violation cog = flexmock("cog") cog.should_receive(:turn).once.and_return(:ok) joint = flexmock("gear", :cog => cog) axle = flexmock("axle", :universal_joint => joint) chassis = flexmock("chassis", :axle => axle) car = flexmock("car", :chassis => chassis) ``` Yuck! The best course of action is to avoid Law of Demeter violations. Then your mocking exploits will be very simple. However, sometimes you have to deal with code that already has a Demeter chain of method calls. So for those cases where you can't avoid it, FlexMock will allow you to easily mock Demeter method chains. Here's an example of Demeter chain mocking: ```ruby # Demeter chain mocking using the short form. car = flexmock("car") car.should_receive( "chassis.axle.universal_joint.cog.turn" => :ok).once ``` You can also use the long form: ```ruby # Demeter chain mocking using the long form. car = flexmock("car") car.should_receive("chassis.axle.universal_joint.cog.turn").once. and_return(:ok) ``` That's it. Anywhere FlexMock accepts a method name for mocking, you can use a demeter chain and FlexMock will attempt to do the right thing. But beware, there are a few limitations. The all the methods in the chain, except for the last one, will mocked to return a mock object. That mock object, in turn, will be mocked so as to respond to the next method in the chain, returning the following mock. And so on. If you try to manually mock out any of the chained methods, you could easily interfer with the mocking specified by the Demeter chain. FlexMock will attempt to catch problems when it can, but there are certainly scenarios where it cannot detect the problem beforehand. ## Examples Refer to the following documents for examples of using FlexMock: * [RSpec Examples](https://github.com/jimweirich/flexmock/blob/master/doc/examples/rspec_examples_spec.rb) * [Test::Unit / MiniTest Examples](https://github.com/jimweirich/flexmock/blob/master/doc/examples/test_unit_examples_test.rb) ## License Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). Copyright 2014- by Sylvain Joyeux (sylvain.joyeux@m4x.org) Licensed under [the MIT license](http://opensource.org/licenses/MIT) # Other stuff * **Author** -- Jim Weirich and Sylvain Joyeux * **Requires** -- Ruby 2.0 or later ## See Also If you like the spy capability of FlexMock, you should check out the [rspec-given gem](http://rubygems.org/gems/rspec-given) that allows you to use Given/When/Then statements in you specifications. ## Warranty This software is provided "as is" and without any express or implied warranties, including, without limitation, the implied warranties of merchantibility and fitness for a particular purpose. flexmock-2.0.4/Rakefile000066400000000000000000000003031263476550700150050ustar00rootroot00000000000000require "bundler/gem_tasks" require "rake/testtask" Rake::TestTask.new(:test) do |t| t.libs << "test" t.libs << "lib" t.test_files = FileList['test/*_test.rb'] end task :default => :test flexmock-2.0.4/doc/000077500000000000000000000000001263476550700141115ustar00rootroot00000000000000flexmock-2.0.4/doc/GoogleExample.rdoc000077500000000000000000000272421263476550700175240ustar00rootroot00000000000000= Extended FlexMock Example Using Google4R Google4R is a simple Ruby wrapper around the Google APIs. In this extended example, we will use FlexMock to test software that uses the Google APIs, without every communicating with Google itself. == Purchase.rb Here is the bit of code that we will be testing... require 'google4r/checkout' require 'item' class Purchase def initialize(config) @frontend = Frontend.new(config) @frontend.tax_table_factory = TaxTableFactory.new end # Purchase the +quantity+ items identified by +item_id+. Return the # confirmation page URL. def purchase(item_id, quantity=1) item = Item.find(item_id) checkout = @frontend.create_checkout_command checkout.cart.create_item do |cart_item| cart_item.name = item.name cart_item.description = item.description cart_item.unit_price = item.unit_price cart_item.quantity = quantity end response = checkout.send_to_google_checkout response.redirect_url end end +FrontEnd+ is a Google4R class that provides a lot of the front end work for talking to the Google APIs. The config object given to the Purchase initializer is simply a hash of values defining the merchant_id, merchant_key and sandbox flag. To use the real Google checkout APIs, you will need to obtains a merchant id and key from Google. Since we will be mocking the Google interaction, we can use dummy values in our test. The tax table factory is required by the Google4R software. We provide the following simplified one. Read the Google API documents for more information. class TestTaxTableFactory def effective_tax_tables_at(time) tax_free_table = TaxTable.new(false) tax_free_table.name = "default table" tax_free_table.create_rule do |rule| rule.area = UsCountryArea.new(UsCountryArea::ALL) rule.rate = 0.0 end return [tax_free_table] end end +Item+ is simply an ActiveRecord class that we are using to hold our purchase item information. It should respond to the +name+, +description+ and +unit_price+ messages. == Testing Without Using External Resources Our first test attempt will be to run the +purchase+ method without talking to either the live Google web services, or hitting an actual ActiveRecord database. === Mocking Active Record The ActiveRecord part is easy to mock. The following will handle it: flexmock(Item).should_receive(:find).with(1).and_return( flexmock("guitar", :name => "Deschutes", :description => "Deschutes model Guitar", :unit_price => Money.new(2400.00))) We have mocked out the +find+ method on +Item+ so that whenever we call find with an integer argument of 1, we will return a mock item that will report its name, description and unit_price. This gives us an item for testing without actually reading the database. === Mocking the Google Web Services Call Next we want to prevent the Google4R API from actually talking to the live web service. Everything that happens in the purchase method is all done locally except for the final call to +send_to_google_checkout+. All we need to do is mock out that one method. flexmock(Google4R::Checkout::CheckoutCommand).new_instances do |instance| instance.should_receive(:send_to_google_checkout).once. and_return(flexmock(:redirect_url => "http://google.response.url")) end When we ask +FrontEnd+ to create a check out command, it returns an instance of Google4R::Checkout::CheckoutCommand. We then use flexmock to specify that when Google4R::Checkout::CheckoutCommand creates a new instance, it should actually return a partial mock of that instance. The block given to the +new_instances+ method allows us to configure the mocked checkout command. We tell it return a response object (yes, another mock) that report our dummy response URL. === The Final Result Here is the complete unit test: def test_buying_a_guitar # Setup flexmock(Item).should_receive(:find).with(1).and_return( flexmock("guitar", :name => "Deschutes", :description => "Deschutes model Guitar", :unit_price => Money.new(2400.00))) flexmock(Google4R::Checkout::CheckoutCommand).new_instances do |instance| instance.should_receive(:send_to_google_checkout).once. and_return(flexmock(:redirect_url => "http://google.response.url")) end # Execute p = Purchase.new({ :merchant_id => 'dummy_id', :merchant_key => 'dummy_key', :use_sandbox => true }) url = p.purchase(1) # Assert assert_equal "http://google.response.url", url end == Testing the Details The above test is fine as far as it goes. It demonstrates how to use mocks to avoid talking to external resources such as databases and web services. But as a unit test, it is sorely lacking in several areas. All the test really demonstrates is that the +send_to_google_checkout+ method is called. There are no tests to ensure that the right item descriptions and prices are correctly stored in the cart. In fact, if we rewrote the purchase method as follows: def purchase(item_id, quantity=1) @frontend.create_checkout_command.send_to_google_checkout.redirect_url end it would still pass the unit test we designed, even though the rewrite is obviously an incorrect implementation. A more complete test is a bit more complicated. Here are the details. === Mocking Active Record Our incorrect version of purchase never calls the +find+ method of Item. We can easily test for that by adding a +once+ constraint one that mock specification. Since find is a read-only method, we don't really care if it is called multiple times, as long as it is called at least one time, so we will add an +at_least+ modifier as well. Finally, we are going to break the guitar mock out into its own declaration. The reason will become obvious in a bit. mock_guitar = flexmock("guitar", :name => "Deschutes", :description => "Deschutes model guitar", :unit_price => Money.new(2400.00)) flexmock(Item).should_receive(:find).with(1).at_least.once. and_return(mock_guitar) === Mocking a Cart Item The next bit is a wee bit complicated, but we will handle it a little bit at a time so that it doesn't become overwhelming. There are three main objects in the Google checkout API that we deal with in the next section.: (1) the checkout command object returned by the front end, (2) the cart object returned by the checkout command, and (3) the item passed to the block in the +create_item+ call. We will tackle them in reverse order, starting with the item objects given to the +create_item+ block. The item must respond to four attribute assignments. This is straightforward to mock, just make sure you include the +once+ constraint so that the assignments are required. mock_item = flexmock("item") mock_item.should_receive(:name=).with(mock_guitar.name).once mock_item.should_receive(:description=).with(mock_guitar.description).once mock_item.should_receive(:unit_price=).with(mock_guitar.unit_price).once mock_item.should_receive(:quantity=).with(1).once Notice how we used the mock_guitar object defined earlier to provide values in the +with+ constraint. This way we don't have to repeat the explicit strings and values we are checking. (Keep it DRY!). === Mocking the Cart The mock cart object will pass the mock_item to a block when the +create_item+ method is called. We specify that with the following: mock_cart = flexmock("cart") mock_cart.should_receive(:create_item).with(Proc).once.and_return { |block| block.call(mock_item) } FlexMock objects can handle blocks passed to them by treating them as the final object in the calling list. Use +Proc+ in the +with+ constraint to match the block and then invoke the block explicitly via block.call(...) in the +and_return+ specification. === Mocking the Checkout Command Finally, we tie it all together by mocking the checkout command. As before, we use +new_instances+ to force newly created checkout commands to be stubbed. This time we not only mockout the +send_to_google+ method, but we also mock the +cart+ command to return the carefully crafted +mock_cart+ object from the previous section. flexmock(Google4R::Checkout::CheckoutCommand).new_instances do |instance| instance.should_receive(:cart).with().once.and_return(mock_cart) instance.should_receive(:send_to_google_checkout).once. and_return(flexmock(:redirect_url => "http://google.response.url")) end === The Final Test Method Here is the complete detailed version of the test method. def test_buying_a_guitar_with_details # Setup mock_guitar = flexmock("guitar", :name => "Deschutes", :description => "Deschutes model guitar", :unit_price => Money.new(2400.00)) flexmock(Item).should_receive(:find).with(1).at_least.once. and_return(mock_guitar) mock_item = flexmock("item") mock_item.should_receive(:name=).with(mock_guitar.name).once mock_item.should_receive(:description=).with(mock_guitar.description).once mock_item.should_receive(:unit_price=).with(mock_guitar.unit_price).once mock_item.should_receive(:quantity=).with(1).once mock_cart = flexmock("cart") mock_cart.should_receive(:create_item).with(Proc).once.and_return { |block| block.call(mock_item) } flexmock(Google4R::Checkout::CheckoutCommand).new_instances do |instance| instance.should_receive(:cart).with().once.and_return(mock_cart) instance.should_receive(:send_to_google_checkout).once. and_return(flexmock(:redirect_url => "http://google.response.url")) end # Execute p = Purchase.new({ :merchant_id => 'dummy_id', :merchant_key => 'dummy_key', :use_sandbox => true }) url = p.purchase(1) # Assert assert_equal "http://google.response.url", url end == Summary Testing with mock objects can get complex. We used seven different mock or partial mock objects in testing the interaction of our code with the Google checkout API. Most testing scenarios won't require that many, but anytime your code touches something external, it might require a mock object for testing. We should stop and ask ourselves: was it worth it? It seems like an awful lot of work just to test a very simple purchase method. Wouldn't it just be easier to just use the Google API directly for testing and forget about the mocks? Perhaps, but using mock objects have several definite advantages: * You can run the test at any time without worrying whether Google, the internet, or anything else is up and connected. * You can easy test for error conditions using mock objects. For example, does your code correctly handle the case where you get an exception when connecting to google? Mocks can easily create those error conditions that are difficult to achieve with real objects. E.g. instance.should_receive(:send_to_google_checkout).once. and_return { raise Google4R::Checkout::GoogleCheckoutError } Some might point out that in the final test method we are hardly using Google4R software at all, most of the code we interact with are mock objects. Doesn't that defeat the purpose of testing? The answer is simple. Always keep in mind what you are testing. The goal of the TestPurchase test case is not the make sure the Google4R code is correct, but that our Purchase class correctly interoperates with it. We do that by carefully stating what methods are called with what arguments and what they return. The test just checks that we are using to external software as we expect it to. We don't actually care about the Google4R software itself in this test case (presumably we do have tests that cover Google4R, but those are different tests). In the end, mock objects are a powerful tool to have in your testing toolbox.flexmock-2.0.4/doc/examples/000077500000000000000000000000001263476550700157275ustar00rootroot00000000000000flexmock-2.0.4/doc/examples/rspec_examples_spec.rb000066400000000000000000000147021263476550700223040ustar00rootroot00000000000000RSpec.configure do |config| config.mock_with :flexmock end describe "Simple Spec" do # Simple stubbing of some methods it "stubs a couple of methods" do m = flexmock(:pi => 3.1416, :e => 2.71) m.pi.should == 3.1416 m.e.should == 2.71 end end describe "Returning Undefined" do # Create a mock object that returns an undefined object for method calls it "returns undefined values" do m = flexmock("mock") m.should_receive(:divide_by).with(0). and_return_undefined m.divide_by(0).should == FlexMock.undefined end end describe "Multiple Queries and Single Updates" do # Expect multiple queries and a single update # Multiple calls to the query method will be allows, and calls may # have any argument list. Each call to query will return the three # element array [1, 2, 3]. The call to update must have a specific # argument of 5. it "queries the db" do db = flexmock('db') db.should_receive(:query).and_return([1,2,3]) db.should_receive(:update).with(5).and_return(nil).once # Test Code db.query db.update(5) end end describe "Ordered Mocks" do # Expect all queries before any updates # All the query message must occur before any of the update # messages. it "queries and updates the database" do db = flexmock('db') db.should_receive(:query).and_return([1,2,3]).ordered db.should_receive(:update).and_return(nil).ordered # test code here db.query db.update end end describe "Ordered Mocks" do # Expect several queries with different parameters # The queries should happen after startup but before finish. The # queries themselves may happen in any order (because they are in # the same order group). The first two queries should happen exactly # once, but the third query (which matches any query call with a # four character parameter) may be called multiple times (but at # least once). Startup and finish must also happen exactly once. # Also note that we use the with method to match # different argument values to figure out what value to return. it "queries the database in a particular order" do db = flexmock('db') db.should_receive(:startup).once.ordered db.should_receive(:query).with("CPWR").and_return(12.3). once.ordered(:queries) db.should_receive(:query).with("MSFT").and_return(10.0). once.ordered(:queries) db.should_receive(:query).with(/^....$/).and_return(3.3). at_least.once.ordered(:queries) db.should_receive(:finish).once.ordered # Test Code db.startup db.query("MSFT") db.query("XYZY") db.query("CPWR") db.finish end end describe "Ordered Mocks" do # Same as above, but using the Record Mode interface # The record mode interface offers much the same features as the # should_receive interface introduced so far, but it # allows the messages to be sent directly to a recording object # rather than be specified indirectly using a symbol. it "records the queries for replay" do db = flexmock('db') db.should_expect do |rec| rec.startup.once.ordered rec.query("CPWR") { 12.3 }.once.ordered(:queries) rec.query("MSFT") { 10.0 }.once.ordered(:queries) rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries) rec.finish.once.ordered end # Test Code db.startup db.query("MSFT") db.query("XYZY") db.query("CPWR") db.finish end end describe "Record Mode" do # Using Record Mode to record a known, good algorithm for testing # Record mode is nice when you have a known, good algorithm that can # use a recording mock object to record the steps. Then you compare # the execution of a new algorithm to behavior of the old using the # recorded expectations in the mock. For this you probably want to # put the recorder in _strict_ mode so that the recorded # expectations use exact matching on argument lists, and strict # ordering of the method calls. # Note: This is most useful when there are no queries on the # mock objects, because the query responses cannot be programmed # into the recorder object. it "compares a know algorithm with a new algorithm" do builder = flexmock('builder') builder.should_expect do |rec| rec.should_be_strict known_good_way_to_build_xml(rec) # record the messages end new_way_to_build_xml(builder) # compare to new way end def known_good_way_to_build_xml(builder) builder.person end def new_way_to_build_xml(builder) builder.person end end describe "Multiple Return Values" do # Expect multiple calls, returning a different value each time # Sometimes you need to return different values for each call to a # mocked method. This example shifts values out of a list for this # effect. it "returns multiple values" do file = flexmock('file') file.should_receive(:gets).with_no_args. and_return("line 1\n", "line 2\n") # test code here file.gets # returns "line 1" file.gets # returns "line 2" end end describe "Ignore Unimportant Messages" do # Ignore uninteresting messages # Generally you need to mock only those methods that return an # interesting value or wish to assert were sent in a particular # manner. Use the should_ignore_missing method to turn # on missing method ignoring. it "ignores unimportant messages" do m = flexmock('m') m.should_receive(:an_important_message).and_return(1).once m.should_ignore_missing # Test Code m.an_important_message m.an_unimportant_message end # When should_ignore_missing is enabled, ignored # missing methods will return an undefined object. Any operation on # the undefined object will return the undefined object. end describe "Partial Mocks" do # Mock just one method on an existing object # The Portfolio class calculate the value of a set of stocks by # talking to a quote service via a web service. Since we don't want # to use a real web service in our unit tests, we will mock the # quote service. it "returns the portfolio value" do flexmock(QuoteService).new_instances do |m| m.should_receive(:quote).and_return(100) end port = Portfolio.new value = port.value # Portfolio calls QuoteService.quote value.should == 100 end class QuoteService end class Portfolio def value qs = QuoteService.new qs.quote end end end flexmock-2.0.4/doc/examples/test_unit_examples_test.rb000066400000000000000000000146401263476550700232340ustar00rootroot00000000000000require 'flexmock/test_unit' class TestSimple < Test::Unit::TestCase # Simple stubbing of some methods def test_simple_mock m = flexmock(:pi => 3.1416, :e => 2.71) assert_equal 3.1416, m.pi assert_equal 2.71, m.e end end class TestUndefined < Test::Unit::TestCase # Create a mock object that returns an undefined object for method calls def test_undefined_values m = flexmock("mock") m.should_receive(:divide_by).with(0). and_return_undefined assert_equal FlexMock.undefined, m.divide_by(0) end end class TestDb < Test::Unit::TestCase # Expect multiple queries and a single update # Multiple calls to the query method will be allows, and calls may # have any argument list. Each call to query will return the three # element array [1, 2, 3]. The call to update must have a specific # argument of 5. def test_db db = flexmock('db') db.should_receive(:query).and_return([1,2,3]) db.should_receive(:update).with(5).and_return(nil).once # Test Code db.query db.update(5) end end class TestOrdered < Test::Unit::TestCase # Expect all queries before any updates # All the query message must occur before any of the update # messages. def test_query_and_update db = flexmock('db') db.should_receive(:query).and_return([1,2,3]).ordered db.should_receive(:update).and_return(nil).ordered # test code here db.query db.update end end class MoreOrdered < Test::Unit::TestCase # Expect several queries with different parameters # The queries should happen after startup but before finish. The # queries themselves may happen in any order (because they are in # the same order group). The first two queries should happen exactly # once, but the third query (which matches any query call with a # four character parameter) may be called multiple times (but at # least once). Startup and finish must also happen exactly once. # Also note that we use the with method to match # different argument values to figure out what value to return. def test_ordered_queries db = flexmock('db') db.should_receive(:startup).once.ordered db.should_receive(:query).with("CPWR").and_return(12.3). once.ordered(:queries) db.should_receive(:query).with("MSFT").and_return(10.0). once.ordered(:queries) db.should_receive(:query).with(/^....$/).and_return(3.3). at_least.once.ordered(:queries) db.should_receive(:finish).once.ordered # Test Code db.startup db.query("MSFT") db.query("XYZY") db.query("CPWR") db.finish end end class EvenMoreOrderedTest < Test::Unit::TestCase # Same as above, but using the Record Mode interface # The record mode interface offers much the same features as the # should_receive interface introduced so far, but it # allows the messages to be sent directly to a recording object # rather than be specified indirectly using a symbol. def test_ordered_queries_in_record_mode db = flexmock('db') db.should_expect do |rec| rec.startup.once.ordered rec.query("CPWR") { 12.3 }.once.ordered(:queries) rec.query("MSFT") { 10.0 }.once.ordered(:queries) rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries) rec.finish.once.ordered end # Test Code db.startup db.query("MSFT") db.query("XYZY") db.query("CPWR") db.finish end end class RecordedTest < Test::Unit::TestCase # Using Record Mode to record a known, good algorithm for testing # Record mode is nice when you have a known, good algorithm that can # use a recording mock object to record the steps. Then you compare # the execution of a new algorithm to behavior of the old using the # recorded expectations in the mock. For this you probably want to # put the recorder in _strict_ mode so that the recorded # expectations use exact matching on argument lists, and strict # ordering of the method calls. # Note: This is most useful when there are no queries on the # mock objects, because the query responses cannot be programmed # into the recorder object. def test_build_xml builder = flexmock('builder') builder.should_expect do |rec| rec.should_be_strict known_good_way_to_build_xml(rec) # record the messages end new_way_to_build_xml(builder) # compare to new way end def known_good_way_to_build_xml(builder) builder.person end def new_way_to_build_xml(builder) builder.person end end class MultipleReturnValueTest < Test::Unit::TestCase # Expect multiple calls, returning a different value each time # Sometimes you need to return different values for each call to a # mocked method. This example shifts values out of a list for this # effect. def test_multiple_gets file = flexmock('file') file.should_receive(:gets).with_no_args. and_return("line 1\n", "line 2\n") # test code here file.gets # returns "line 1" file.gets # returns "line 2" end end class IgnoreUnimportantMessages < Test::Unit::TestCase # Ignore uninteresting messages # Generally you need to mock only those methods that return an # interesting value or wish to assert were sent in a particular # manner. Use the should_ignore_missing method to turn # on missing method ignoring. def test_an_important_message m = flexmock('m') m.should_receive(:an_important_message).and_return(1).once m.should_ignore_missing # Test Code m.an_important_message m.an_unimportant_message end # When should_ignore_missing is enabled, ignored # missing methods will return an undefined object. Any operation on # the undefined object will return the undefined object. end class PartialMockTest < Test::Unit::TestCase # Mock just one method on an existing object # The Portfolio class calculate the value of a set of stocks by # talking to a quote service via a web service. Since we don't want # to use a real web service in our unit tests, we will mock the # quote service. def test_portfolio_value flexmock(QuoteService).new_instances do |m| m.should_receive(:quote).and_return(100) end port = Portfolio.new value = port.value # Portfolio calls QuoteService.quote assert_equal 100, value end class QuoteService end class Portfolio def value qs = QuoteService.new qs.quote end end end flexmock-2.0.4/doc/index.rdoc000066400000000000000000000021451263476550700160730ustar00rootroot00000000000000= Flex Mock -- Making Mocking Easy FlexMock is a simple, but flexible, mock object library for Ruby unit testing. This is the API documentation site for flexmock. You can find the user documentation at http://github.com/jimweirich/flexmock == Links * User Guide -- http://github.com/jimweirich/flexmock * API Documents -- http://flexmock.rubyforge.org * RubyGems -- Install with: `gem install flexmock` * Source -- https://github.com/jimweirich/flexmock * Bug Reports / Issue Tracking -- https://github.com/jimweirich/flexmock/issues * Continuous Integration -- http://travis-ci.org/#!/jimweirich/flexmock == License Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). All rights reserved. Permission is granted for use, copying, modification, distribution, and distribution of modified versions of this work as long as the above copyright notice is included. == Warranty This software is provided "as is" and without any express or implied warranties, including, without limitation, the implied warranties of merchantibility and fitness for a particular purpose. flexmock-2.0.4/doc/jamis.rb000066400000000000000000000261171263476550700155500ustar00rootroot00000000000000module RDoc module Page FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif" STYLE = < pre { padding: 0.5em; border: 1px dotted black; background: #FFE; } CSS XHTML_PREAMBLE = %{ } HEADER = XHTML_PREAMBLE + < %title% ENDHEADER FILE_PAGE = <
File
%short_name%
Path: %full_path% IF:cvsurl  (CVS) ENDIF:cvsurl
Modified: %dtm_modified%

HTML ################################################################### CLASS_PAGE = < %classmod%
%full_name% IF:parent ENDIF:parent
In: START:infiles HREF:full_path_url:full_path: IF:cvsurl  (CVS) ENDIF:cvsurl END:infiles
Parent: IF:par_url ENDIF:par_url %parent% IF:par_url ENDIF:par_url
HTML ################################################################### METHOD_LIST = < IF:diagram
%diagram%
ENDIF:diagram IF:description
%description%
ENDIF:description IF:requires
Required Files
    START:requires
  • HREF:aref:name:
  • END:requires
ENDIF:requires IF:toc
Contents
ENDIF:toc IF:methods
Methods
    START:methods
  • HREF:aref:name:
  • END:methods
ENDIF:methods IF:includes
Included Modules
    START:includes
  • HREF:aref:name:
  • END:includes
ENDIF:includes START:sections IF:sectitle IF:seccomment
%seccomment%
ENDIF:seccomment ENDIF:sectitle IF:classlist
Classes and Modules
%classlist% ENDIF:classlist IF:constants
Constants
START:constants IF:desc ENDIF:desc END:constants
%name% = %value%
  %desc%
ENDIF:constants IF:attributes
Attributes
START:attributes END:attributes
IF:rw [%rw%] ENDIF:rw %name% %a_desc%
ENDIF:attributes IF:method_list START:method_list IF:methods
%type% %category% methods
START:methods
IF:callseq %callseq% ENDIF:callseq IFNOT:callseq %name%%params% ENDIF:callseq IF:codeurl [ source ] ENDIF:codeurl
IF:m_desc
%m_desc%
ENDIF:m_desc IF:aka
This method is also aliased as START:aka %name% END:aka
ENDIF:aka IF:sourcecode
%sourcecode%
ENDIF:sourcecode
END:methods ENDIF:methods END:method_list ENDIF:method_list END:sections HTML FOOTER = < ENDFOOTER BODY = HEADER + <
#{METHOD_LIST}
#{FOOTER} ENDBODY ########################## Source code ########################## SRC_PAGE = XHTML_PREAMBLE + < %title%
%code%
HTML ########################## Index ################################ FR_INDEX_BODY = <
START:entries %name%
END:entries
HTML CLASS_INDEX = FILE_INDEX METHOD_INDEX = FILE_INDEX INDEX = XHTML_PREAMBLE + < %title% IF:inline_source ENDIF:inline_source IFNOT:inline_source ENDIF:inline_source <body bgcolor="white"> Click <a href="html/index.html">here</a> for a non-frames version of this page. </body> HTML end end flexmock-2.0.4/doc/releases/000077500000000000000000000000001263476550700157145ustar00rootroot00000000000000flexmock-2.0.4/doc/releases/flexmock-0.4.0.rdoc000066400000000000000000000055441263476550700210420ustar00rootroot00000000000000= FlexMock 0.4.0 Released FlexMock is a flexible mocking library for use in Ruby's Test::Unit test framework. Version 0.4.0 enhances FlexMock with the ability to stub and mock methods in existing objects. == Changes === New Features in 0.4.0 * You can now use the flexstub(object) method to mock or stub individual methods in an existing object. The original definitions of the methods are restored at the end of a test. * The and_return (and its alias, returns) now accepts a list of arguments and will return the values in the list one at a time for each successive call to the mocked method. * The flexmock() method now accepts an initialization block so that a mock can be created and configured in one step without using a local variable. This is really handy when mocking factory or creation methods that in turn return a mock. == What is FlexMock? FlexMock is a flexible Ruby mocking library that works with Ruby's Test::Unit framework to create easy to use mocks. === Features * Easy integration with Test::Unit. Mocks created with the flexmock method are automatically verified at the end of the test. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock' class TestDog < Test::Unit::TestCase include FlexMock::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://onestepback.org/software/flexmock for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability FlexMock is distributed with Rails, or you can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://onestepback.org/software/flexmock/ -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.4.1.rdoc000066400000000000000000000045701263476550700210410ustar00rootroot00000000000000= FlexMock 0.4.1 Released FlexMock is a flexible mocking library for use in Ruby's Test::Unit test framework. Version 0.4.0 enhances FlexMock with the ability to stub and mock methods in existing objects. == New in 0.4.1 Coming fast on the heels of 0.4.0, version 0.4.1 fixes a problem with mocking methods that have the same name as methods defined in Kernel. == What is FlexMock? FlexMock is a flexible Ruby mocking library that works with Ruby's Test::Unit framework to create easy to use mocks. === Features * Easy integration with Test::Unit. Mocks created with the flexmock method are automatically verified at the end of the test. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock' class TestDog < Test::Unit::TestCase include FlexMock::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://onestepback.org/software/flexmock for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability FlexMock is distributed with Rails, or you can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://onestepback.org/software/flexmock/ -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.4.2.rdoc000066400000000000000000000045561263476550700210460ustar00rootroot00000000000000= FlexMock 0.4.2 Released FlexMock is a flexible mocking library for use in Ruby's Test::Unit test framework. Version 0.4.0 enhances FlexMock with the ability to stub and mock methods in existing objects. == New in 0.4.2 Release 0.4.2 contains a fix for multiple definitions of a class method stub so that the correct original definition is retained. == What is FlexMock? FlexMock is a flexible Ruby mocking library that works with Ruby's Test::Unit framework to create easy to use mocks. === Features * Easy integration with Test::Unit. Mocks created with the flexmock method are automatically verified at the end of the test. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock' class TestDog < Test::Unit::TestCase include FlexMock::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://onestepback.org/software/flexmock for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability FlexMock is distributed with Rails, or you can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://onestepback.org/software/flexmock/ -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.4.3.rdoc000066400000000000000000000045301263476550700210370ustar00rootroot00000000000000= FlexMock 0.4.3 Released FlexMock is a flexible mocking library for use in Ruby's Test::Unit test framework. Version 0.4.0 enhances FlexMock with the ability to stub and mock methods in existing objects. == New in 0.4.3 Release 0.4.3 contains a fix for handling non-direct class methods properly (bug report from Scott Barron). == What is FlexMock? FlexMock is a flexible Ruby mocking library that works with Ruby's Test::Unit framework to create easy to use mocks. === Features * Easy integration with Test::Unit. Mocks created with the flexmock method are automatically verified at the end of the test. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock' class TestDog < Test::Unit::TestCase include FlexMock::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://onestepback.org/software/flexmock for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability FlexMock is distributed with Rails, or you can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://onestepback.org/software/flexmock/ -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.5.0.rdoc000077500000000000000000000056511263476550700210450ustar00rootroot00000000000000= FlexMock 0.5.0 Released FlexMock is a flexible mocking library for use in Ruby's Test::Unit test framework. Version 0.5.0 adds the ability to automatically stub any instance created by an existing class. == New in 0.5.0 * flexstub(obj) will now accept a block argument in the same way that flexmock() does. * When stubbing Class objects, the any_instance method can be used to automatically stub any instance object created by the class. For example, if you wish that any Connection object created during a test has a stubbed "send" method, you could do the following: def test_connections flexstub(Connection).any_instance do |new_con| new_con.should_receive(:send).and_return(0) end connection = Connection.new connection.send # This calls the stubbed version of send. end Only objects created during the test will be automatically stubbed. Existing objects are unaffected. == What is FlexMock? FlexMock is a flexible Ruby mocking library that works with Ruby's Test::Unit framework to create easy to use mocks. === Features * Easy integration with Test::Unit. Mocks created with the flexmock method are automatically verified at the end of the test. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock' class TestDog < Test::Unit::TestCase include FlexMock::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://onestepback.org/software/flexmock for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://onestepback.org/software/flexmock/ -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.5.1.rdoc000066400000000000000000000043531263476550700210410ustar00rootroot00000000000000= FlexMock 0.5.0 Released FlexMock is a flexible mocking library for use in Ruby's Test::Unit test framework. Version 0.5.1 is a minor bug fix release. == New in 0.5.1 * Version 0.5.1 fixes a problem that caused some older versions of RCov to core dump. == What is FlexMock? FlexMock is a flexible Ruby mocking library that works with Ruby's Test::Unit framework to create easy to use mocks. === Features * Easy integration with Test::Unit. Mocks created with the flexmock method are automatically verified at the end of the test. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock' class TestDog < Test::Unit::TestCase include FlexMock::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://onestepback.org/software/flexmock for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://onestepback.org/software/flexmock/ -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.6.0.rdoc000077500000000000000000000107571263476550700210510ustar00rootroot00000000000000= FlexMock 0.6.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Version 0.6.0 introduces a number of API enhancements to make testing with mocks even easier than before. == New in 0.6.0 * Better integration with Test::Unit (no need to explicitly include FlexMock::TestCase). * Integration with RSpec (version 0.9.0 or later of RSpec is required). * The +flexmock+ method will now create both regular mocks and partial mocks. flexmock() # => a full mock flexmock(person) # => a partial mock based on person (+flexstub+ is still included for backwards compatibility). * Quick and simple mocks my now be created using an expectation hash. For example: flexmock(:foo => 10, :bar => "Hello") will create a mock with two methods, :foo and :bar,defined. :foo will return 10 when invoked, and :bar will return "Hello". * The +should_receive+ method will now allow multiple methods (with the same constraints) be defined in a single call. For example, the following declares that both :read and :write need to be called at least one time each on the mock object. flexmock.should_receive(:read, :write).at_least.once * +should_receive+ now will allow expectation hashes as arguments. This is similar to the list of methods, but allows each defined method to have its own return value. flexmock.should_receive(:name => "John", :age => 32) * In addition to using a block for defining constrains, constraints may now be applied directly to the return value of +new_instances+. Combined with the expectation hashes supported by +should_receive+, simple mocking scenarios have become much more succinct. For example: flexmock(Person).new_instances.should_receive(:name => "John", :age => 32) * Improved implementation, allowing for more flexible use and greater consistency between full mock and partial mocks. * Version 0.6.0 also includes a fix for an incompatibility with some older versions of RCov. The FlexMock Rakefile now includes a RCov task (and we have 100% code coverage). == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.6.1.rdoc000066400000000000000000000052721263476550700210430ustar00rootroot00000000000000= FlexMock 0.6.1 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Version 0.6.1 introduces a number minor bug fixes. == New in 0.6.1 * Fixed several bugs related to partial mocks and ordering and mocking field assignments. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.6.2.rdoc000066400000000000000000000060251263476550700210410ustar00rootroot00000000000000= FlexMock 0.6.2 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Version 0.6.2 introduces a two minor enhancements. == New in 0.6.2 * When creating a partial mock using a block, flexmock() now returns the domain object rather than the mock proxy. This allows the following to work: obj = flexmock(Something.new) { |m| m.should_receive(:hi).once } obj.hi See http://onestepback.org/index.cgi/Tech/Ruby/FlexMockReturns.red for more details. * The +and_raise+ method is now supported for directly specifying that exceptions will be thrown from a mock. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.6.3.rdoc000066400000000000000000000074111263476550700210420ustar00rootroot00000000000000= FlexMock 0.6.3 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Version 0.6.3 introduces several enhancements. == New in 0.6.3 * Added the flexmodel() method for better support when mocking ActiveRecord objects. flexmodel(YourModelClass) will return a pure mock object that responds to some basic ActiveRecord methods with reasonable defaults. The flexmodel() method is optional and you need to require 'flexmock/activerecord' to active it. * The flexmock() method now _always_ returns a combination domain object / mock object. This means the object return can handle domain methods and mock-specific methods (such as should_receive and mock_teardown). * A side effect of always returning a domain/mock object is that partial mocks are now enhanced with about 5 or 6 extra methods. Since partial mocks are real objects with just a few methods mocked, there is a (small) potential for a method name conflict. FlexMock now supports a safe-mode for partial mocks if this is an issue in particular case (see the RDoc README file for more details). * Fixed a small bug where attempting to mock a method that the partial mock claims to respond to, but doesn't actually have defined would cause an error. This tended to happen on active record objects where attributes are dynamically handled. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.6.4.rdoc000066400000000000000000000077641263476550700210560ustar00rootroot00000000000000= FlexMock 0.6.4 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Version 0.6.4 and 0.6.3 introduce several enhancements. == New in 0.6.4 (and 0.6.3) * Added the flexmock(:model, ...) method for better support when mocking ActiveRecord objects. flexmock(:model, YourModelClass) will return a pure mock object that responds to some basic ActiveRecord methods with reasonable defaults. * The flexmock() method now _always_ returns a combination domain object / mock object. This means the object return can handle domain methods and mock-specific methods (such as should_receive and mock_teardown). * A side effect of always returning a domain/mock object is that partial mocks are now enhanced with about 5 or 6 extra methods. Since partial mocks are real objects with just a few methods mocked, there is a (small) potential for a method name conflict. FlexMock now supports a safe-mode for partial mocks if this is an issue in particular case (see the RDoc README file for more details). * Fixed a small bug where attempting to mock a method that the partial mock claims to respond to, but doesn't actually have defined would cause an error. This tended to happen on active record objects where attributes are dynamically handled. NOTE: 0.6.4 improves the interface for mocking ActiveRecord model objects. The flexmodel() method was too visually similar to flexmock() and was to easy to get confused when reading code. Release 0.6.3's flexmodel() method has been removed and a new :model mode has been added to flexmock(). == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.7.0.rdoc000066400000000000000000000114011263476550700210320ustar00rootroot00000000000000= FlexMock 0.7.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Version 0.7.0 introduces several enhancements. == New in 0.7.0 * FlexMock now supports the ability to mock a chain of method calls automatically. For example: car = flexmock("car", "chassis.engine.piston.stroke" => :ok) assert_equal :ok, car.chassis.engine.piston.stroke will create a sequence of mocks so that the "chassis" call will return a mock that responds to "engine", which returns a mock that responds to "piston", which returns a mock that responds to "stroke". This facility makes mocking legacy code that violates the Law of Demeter a bit easier to deal with. * Added the the +and_yield+ constraint to FlexMock expectations. This allows the user to easily specify values passed to any block given to the mock method. * Globally ordering of mocked calls is now optionally available. When a mock method is globally ordered, it must be called in the correct order with regard to all other globally ordered methods. Non-global ordering only requires that the method calls be ordered with regard to other methods on the same mock object. * The output for mock.inspect was modified to be much more consise, so that test framework error messages do not overwhelm the output. * In order to clean up the method namespace, a number of internally used methods were deprecated. All non-public methods that get added to mocks, partial mocks or test frameworks now begin with "flexmock_" (rather than "mock_"). The "mock_*" versions are still available, but will display deprecation warnings when used. The deprecated "mock_*" methods will be removed in a future version. * Additionally, the ancient "mock_handle" method has been deprecated (prints a warning when used), and will be removed in a future version. Users are encouraged to use the newer "should_receive" method instead. == New Features Added in 0.6.x In case you missed them, here are a number of features that were added during the 0.6.x versions of FlexMock. * ActiveRecord mocking support with flexmock(:model, ModelName). * Better partial mock definitions, including a "safe-mode" that minimizes mock namespace pollution in the domain object. * Support for +and_raise+ constraint to ease the definition of mocks that raise exceptions. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.7.1.rdoc000066400000000000000000000053431263476550700210430ustar00rootroot00000000000000= FlexMock 0.7.1 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Version 0.7.1 includes a minor bug fix. == Bug Fixes n 0.7.1 * A bug in demeter mocking in 0.7.0 prevented the mocking of operators. This has been fixed. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.8.0.rdoc000066400000000000000000000064761263476550700210530ustar00rootroot00000000000000= FlexMock 0.8.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. It is a minor release that contains some new funtionality. == New Features in 0.8.0 * When should_ignore_missing is specified, the mock will return an undefined object for any method calls that are ignored. * A user can also specify an undefined object to be returned explicitly by using FlexMock.undefined. * Expectations may now be marked with "by_default". Default expectations will be used unless a non-default expectation is given for a matching method name. * The :respond_to? method on mocks will now accept multiple arguments. This eases the testing of models in certains situations. * An experimental view mocker method is availble to mock out views in Rails controller tests. See flexmock/rails/view_mocking.rb for more details. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.8.2.rdoc000066400000000000000000000060661263476550700210500ustar00rootroot00000000000000= FlexMock 0.8.2 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 0.8.2 is a minor release with a few bug fixes. == Bug Fixes in 0.8.2 * FlexMock partial mocks will now override any preexisting definitions for "should_receive". Previously, FlexMock would honor preexisting defintions, but an RSpec on Rails bug loads the RSpec mocks, even when other mock libraries are configured. This allows flexmock to correctly use partial mocks in the presence of an ill-behaved mock library. * View Stubbing has been updated to work with Rails 2.0.2. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.8.3.rdoc000066400000000000000000000053571263476550700210530ustar00rootroot00000000000000= FlexMock 0.8.3 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 0.8.3 is a minor release with a few bug fixes. == Bug Fixes in 0.8.3 * Fixed a bug where the by_default option was not completely honored in some edge cases. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.8.4.rdoc000066400000000000000000000053301263476550700210430ustar00rootroot00000000000000= FlexMock 0.8.4 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 0.8.4 is a minor release with a few bug fixes. == Bug Fixes in 0.8.4 * The should_render_view method is now compatible with Rails 2.2.2. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.8.5.rdoc000066400000000000000000000054151263476550700210500ustar00rootroot00000000000000= FlexMock 0.8.5 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 0.8.5 is a minor release with a few bug fixes. == Bug Fixes in 0.8.5 * Fixed warning about a void context. * hsh() argument matcher now reports its matching constraints in error messages. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) Otherwise, you can get it from the more traditional places: Download:: http://rubyforge.org/project/showfiles.php?group_id=170 You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-0.9.0.rdoc000066400000000000000000000051421263476550700210410ustar00rootroot00000000000000= FlexMock 0.9.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 0.8.5 is a minor release with a few bug fixes. == Ruby 1.9.3 Compatibility * Fixed a number of minor warnings reported by the 1.9.3 version of Ruby. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: require 'test/unit' require 'flexmock/test_unit' class TestDog < Test::Unit::TestCase def test_dog_wags_tail_when_happy tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-1.0.0.rdoc000066400000000000000000000076351263476550700210420ustar00rootroot00000000000000= FlexMock 1.0.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 1.0.0 is a major release with some nice features and bug fixes. == Changes in 1.0.0 === Features * Mocks may now have a base class that limits what methods may be mocked. This allows early detection of outdated mock setups when the methods in the class are refactored. * Spy assertions are now allowed. The verification of the calling of mocked methods may now be done in the "then" portion of the test, after the code under test has been run. This allows for much more natural Given/When/Then style testing. * A custom assert method (assert_spy_called) has been added to make spy assertions easy when using Test::Unit or MiniTest. * An RSpec matcher (have_received) has been added to make spy assertions easy when using RSpec. === Bug Fixes * Now correctly handling the mocking of meta-programmed methods. * Using the documented +singleton_methods+ method. * Accidently trying to partial mock a regular mock is now a no-op. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: RSpec.configure do |config| config.mock_with :flexmock end describe Dog do it "wags its tail when happy" do tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. Here's the same thing using the new spy support: describe Dog do it "wags its tail when happy" do tail = flexmock("tail") dog = Dog.new(tail) dog.happy tail.should have_received(:wag) end end This style works particularly well with the rspec-given library. require 'rspec/given' describe Dog do context "when the dog is happy" do Given(:tail) { flexmock(:on, Tail) } Given(:dog) { Dog.new(tail) } When { dog.happy } Then { tail.should have_received(:wag) } end end See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-1.0.3.rdoc000066400000000000000000000103321263476550700210310ustar00rootroot00000000000000= FlexMock 1.0.3 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 1.0.0 is a minor release with a few bug fixes. == Changes in 1.0.3 === Features * Better error messages when a mock is called the incorrect number of times * Better stack output when validations fail during teardown. == Changes in 1.0.2 === Bug Fixes * Quick definitions now obey base class restrictions == Changes in 1.0.1 === Features * Better Ruby 1.8 compatibility == Changes in 1.0.0 === Features * Mocks may now have a base class that limits what methods may be mocked. This allows early detection of outdated mock setups when the methods in the class are refactored. * Spy assertions are now allowed. The verification of the calling of mocked methods may now be done in the "then" portion of the test, after the code under test has been run. This allows for much more natural Given/When/Then style testing. * A custom assert method (assert_spy_called) has been added to make spy assertions easy when using Test::Unit or MiniTest. * An RSpec matcher (have_received) has been added to make spy assertions easy when using RSpec. === Bug Fixes * Now correctly handling the mocking of meta-programmed methods. * Using the documented +singleton_methods+ method. * Accidently trying to partial mock a regular mock is now a no-op. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: RSpec.configure do |config| config.mock_with :flexmock end describe Dog do it "wags its tail when happy" do tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. Here's the same thing using the new spy support: describe Dog do it "wags its tail when happy" do tail = flexmock("tail") dog = Dog.new(tail) dog.happy tail.should have_received(:wag) end end This style works particularly well with the rspec-given library. require 'rspec/given' describe Dog do context "when the dog is happy" do Given(:tail) { flexmock(:on, Tail) } Given(:dog) { Dog.new(tail) } When { dog.happy } Then { tail.should have_received(:wag) } end end See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-1.0.4.rdoc000066400000000000000000000104241263476550700210340ustar00rootroot00000000000000= FlexMock 1.0.4 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 1.0.3 is a minor release with a few bug fixes. == Changes in 1.0.4 === Features * Add spy capability. == Changes in 1.0.3 === Features * Better error messages when a mock is called the incorrect number of times * Better stack output when validations fail during teardown. == Changes in 1.0.2 === Bug Fixes * Quick definitions now obey base class restrictions == Changes in 1.0.1 === Features * Better Ruby 1.8 compatibility == Changes in 1.0.0 === Features * Mocks may now have a base class that limits what methods may be mocked. This allows early detection of outdated mock setups when the methods in the class are refactored. * Spy assertions are now allowed. The verification of the calling of mocked methods may now be done in the "then" portion of the test, after the code under test has been run. This allows for much more natural Given/When/Then style testing. * A custom assert method (assert_spy_called) has been added to make spy assertions easy when using Test::Unit or MiniTest. * An RSpec matcher (have_received) has been added to make spy assertions easy when using RSpec. === Bug Fixes * Now correctly handling the mocking of meta-programmed methods. * Using the documented +singleton_methods+ method. * Accidently trying to partial mock a regular mock is now a no-op. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: RSpec.configure do |config| config.mock_with :flexmock end describe Dog do it "wags its tail when happy" do tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. Here's the same thing using the new spy support: describe Dog do it "wags its tail when happy" do tail = flexmock("tail") dog = Dog.new(tail) dog.happy tail.should have_received(:wag) end end This style works particularly well with the rspec-given library. require 'rspec/given' describe Dog do context "when the dog is happy" do Given(:tail) { flexmock(:on, Tail) } Given(:dog) { Dog.new(tail) } When { dog.happy } Then { tail.should have_received(:wag) } end end See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-1.1.0.rdoc000066400000000000000000000077521263476550700210430ustar00rootroot00000000000000= FlexMock 1.1.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 1.1.0 is a minor release with a few bug fixes and some small features. == Changes in 1.1.0 === Features * Add block support to pass_thru. == Changes in 1.0.0 === Features * Mocks may now have a base class that limits what methods may be mocked. This allows early detection of outdated mock setups when the methods in the class are refactored. * Spy assertions are now allowed. The verification of the calling of mocked methods may now be done in the "then" portion of the test, after the code under test has been run. This allows for much more natural Given/When/Then style testing. * A custom assert method (assert_spy_called) has been added to make spy assertions easy when using Test::Unit or MiniTest. * An RSpec matcher (have_received) has been added to make spy assertions easy when using RSpec. === Bug Fixes * Now correctly handling the mocking of meta-programmed methods. * Using the documented +singleton_methods+ method. * Accidently trying to partial mock a regular mock is now a no-op. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: RSpec.configure do |config| config.mock_with :flexmock end describe Dog do it "wags its tail when happy" do tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. Here's the same thing using the new spy support: describe Dog do it "wags its tail when happy" do tail = flexmock("tail") dog = Dog.new(tail) dog.happy tail.should have_received(:wag) end end This style works particularly well with the rspec-given library. require 'rspec/given' describe Dog do context "when the dog is happy" do Given(:tail) { flexmock(:on, Tail) } Given(:dog) { Dog.new(tail) } When { dog.happy } Then { tail.should have_received(:wag) } end end See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-1.2.0.rdoc000066400000000000000000000101151263476550700210270ustar00rootroot00000000000000= FlexMock 1.2.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. Release 1.2.0 is a minor release with a few bug fixes and some simple features. == Changes in 1.2.0 === Features * Add auto configure by requiring 'flexmock/rspec/configure'. == Changes in 1.1.0 === Features * Add block support to pass_thru. == Changes in 1.0.0 === Features * Mocks may now have a base class that limits what methods may be mocked. This allows early detection of outdated mock setups when the methods in the class are refactored. * Spy assertions are now allowed. The verification of the calling of mocked methods may now be done in the "then" portion of the test, after the code under test has been run. This allows for much more natural Given/When/Then style testing. * A custom assert method (assert_spy_called) has been added to make spy assertions easy when using Test::Unit or MiniTest. * An RSpec matcher (have_received) has been added to make spy assertions easy when using RSpec. === Bug Fixes * Now correctly handling the mocking of meta-programmed methods. * Using the documented +singleton_methods+ method. * Accidently trying to partial mock a regular mock is now a no-op. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: RSpec.configure do |config| config.mock_with :flexmock end describe Dog do it "wags its tail when happy" do tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. Here's the same thing using the new spy support: describe Dog do it "wags its tail when happy" do tail = flexmock("tail") dog = Dog.new(tail) dog.happy tail.should have_received(:wag) end end This style works particularly well with the rspec-given library. require 'rspec/given' describe Dog do context "when the dog is happy" do Given(:tail) { flexmock(:on, Tail) } Given(:dog) { Dog.new(tail) } When { dog.happy } Then { tail.should have_received(:wag) } end end See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-1.3.0.rdoc000066400000000000000000000105621263476550700210360ustar00rootroot00000000000000= FlexMock 1.3.0 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. This release is a minor release with a few bug fixes and some simple features. == Changes in 1.3.0 === Features * Add 'and' and 'on' modifiers for the RSpec spy matcher. * Add 'and' and 'on' options to the assert_spy_called test method. * General documentation improvement. === Bug Fixes * Fix bug in should_fail test helper that was not detecting failed failures. == Changes in 1.2.0 === Features * Add auto configure by requiring 'flexmock/rspec/configure'. == Changes in 1.1.0 === Features * Add block support to pass_thru. == Changes in 1.0.0 === Features * Mocks may now have a base class that limits what methods may be mocked. This allows early detection of outdated mock setups when the methods in the class are refactored. * Spy assertions are now allowed. The verification of the calling of mocked methods may now be done in the "then" portion of the test, after the code under test has been run. This allows for much more natural Given/When/Then style testing. * A custom assert method (assert_spy_called) has been added to make spy assertions easy when using Test::Unit or MiniTest. * An RSpec matcher (have_received) has been added to make spy assertions easy when using RSpec. === Bug Fixes * Now correctly handling the mocking of meta-programmed methods. * Using the documented +singleton_methods+ method. * Accidently trying to partial mock a regular mock is now a no-op. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: RSpec.configure do |config| config.mock_with :flexmock end describe Dog do it "wags its tail when happy" do tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. Here's the same thing using the new spy support: describe Dog do it "wags its tail when happy" do tail = flexmock("tail") dog = Dog.new(tail) dog.happy tail.should have_received(:wag) end end This style works particularly well with the rspec-given library. require 'rspec/given' describe Dog do context "when the dog is happy" do Given(:tail) { flexmock(:on, Tail) } Given(:dog) { Dog.new(tail) } When { dog.happy } Then { tail.should have_received(:wag) } end end See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/doc/releases/flexmock-1.3.1.rdoc000066400000000000000000000107411263476550700210360ustar00rootroot00000000000000= FlexMock 1.3.1 Released FlexMock is a flexible mocking library for use in unit testing and behavior specification in Ruby. This release is a minor release with a few bug fixes and some simple features. == Changes in 1.3.1 * Removed use of assert_block (which is deprecated in MiniTest). * Documentation fixes. == Changes in 1.3.0 === Features * Add 'and' and 'on' modifiers for the RSpec spy matcher. * Add 'and' and 'on' options to the assert_spy_called test method. * General documentation improvement. === Bug Fixes * Fix bug in should_fail test helper that was not detecting failed failures. == Changes in 1.2.0 === Features * Add auto configure by requiring 'flexmock/rspec/configure'. == Changes in 1.1.0 === Features * Add block support to pass_thru. == Changes in 1.0.0 === Features * Mocks may now have a base class that limits what methods may be mocked. This allows early detection of outdated mock setups when the methods in the class are refactored. * Spy assertions are now allowed. The verification of the calling of mocked methods may now be done in the "then" portion of the test, after the code under test has been run. This allows for much more natural Given/When/Then style testing. * A custom assert method (assert_spy_called) has been added to make spy assertions easy when using Test::Unit or MiniTest. * An RSpec matcher (have_received) has been added to make spy assertions easy when using RSpec. === Bug Fixes * Now correctly handling the mocking of meta-programmed methods. * Using the documented +singleton_methods+ method. * Accidently trying to partial mock a regular mock is now a no-op. == What is FlexMock? FlexMock is a flexible framework for creating mock object for testing. When running unit tests, it is often desirable to use isolate the objects being tested from the "real world" by having them interact with simplified test objects. Sometimes these test objects simply return values when called, other times they verify that certain methods were called with particular arguments in a particular order. FlexMock makes creating these test objects easy. === Features * Easy integration with both Test::Unit and RSpec. Mocks created with the flexmock method are automatically verified at the end of the test or example. * A fluent interface that allows mock behavior to be specified very easily. * A "record mode" where an existing implementation can record its interaction with a mock for later validation against a new implementation. * Easy mocking of individual methods in existing, non-mock objects. * Easy mocking of chains of method calls. * The ability to cause classes to instantiate test instances (instead of real instances) for the duration of a test. === Example Suppose you had a Dog object that wagged a tail when it was happy. Something like this: class Dog def initialize(a_tail) @tail = a_tail end def happy @tail.wag end end To test the +Dog+ class without a real +Tail+ object (perhaps because real +Tail+ objects activate servos in some robotic equipment), you can do something like this: RSpec.configure do |config| config.mock_with :flexmock end describe Dog do it "wags its tail when happy" do tail = flexmock("tail") tail.should_receive(:wag).once dog = Dog.new(tail) dog.happy end end FlexMock will automatically verify that the mocked tail object received the message +wag+ exactly one time. If it doesn't, the test will not pass. Here's the same thing using the new spy support: describe Dog do it "wags its tail when happy" do tail = flexmock("tail") dog = Dog.new(tail) dog.happy tail.should have_received(:wag) end end This style works particularly well with the rspec-given library. require 'rspec/given' describe Dog do context "when the dog is happy" do Given(:tail) { flexmock(:on, Tail) } Given(:dog) { Dog.new(tail) } When { dog.happy } Then { tail.should have_received(:wag) } end end See the FlexMock documentation at http://flexmock.rubyforge.org for details on specifying arguments and return values on mocked methods, as well as a simple technique for mocking tail objects when the Dog class creates the tail objects directly. == Availability You can make sure you have the latest version with a quick RubyGems command: gem install flexmock (you may need root/admin privileges) You will find documentation at: http://flexmock.rubyforge.org. -- Jim Weirich flexmock-2.0.4/flexmock.blurb000066400000000000000000000007711263476550700162110ustar00rootroot00000000000000name: flexmock document: http://onestepback.org/software/flexmock download: http://onestepback.org/packages/flexmock description: >

FlexMock is the outcome of a frustrating evening of trying to use the original mock object by Nat Pryce. Nat's mock object is really cool, but it assumes that we know the exact calling order of all the methods to the mock object. I really feel that over-constrains the solution code. This little quicky seems to meet my needs fairly well.

flexmock-2.0.4/flexmock.gemspec000066400000000000000000000020731263476550700165230ustar00rootroot00000000000000require './lib/flexmock/version.rb' spec = Gem::Specification.new do |s| #### Basic information. s.name = 'flexmock' s.version = FlexMock::VERSION s.summary = "Simple and Flexible Mock Objects for Testing" s.description = %{ FlexMock is a extremely simple mock object class compatible with the Minitest framework. Although the FlexMock's interface is simple, it is very flexible. } s.required_ruby_version = ">= 2.0" s.license = 'MIT' #### Dependencies and requirements. s.add_development_dependency 'minitest' s.add_development_dependency 'rake' s.add_development_dependency 'coveralls' #### Which files are to be included in this gem? Everything! (Except CVS directories.) s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } s.require_paths = ['lib'] # Use these for libraries.] #### Author and project details. s.authors = ["Jim Weirich", "Sylvain Joyeux"] s.email = "sylvain.joyeux@m4x.org" s.homepage = "https://github.com/doudou/flexmock" end flexmock-2.0.4/install.rb000066400000000000000000000017001263476550700153350ustar00rootroot00000000000000require 'rbconfig' require 'find' require 'ftools' include Config def indir(newdir) olddir = Dir.pwd Dir.chdir(newdir) yield ensure Dir.chdir(olddir) end $ruby = CONFIG['ruby_install_name'] $sitedir = CONFIG["sitelibdir"] unless $sitedir version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"] $libdir = File.join(CONFIG["libdir"], "ruby", version) $sitedir = $:.find {|x| x =~ /site_ruby/} if !$sitedir $sitedir = File.join($libdir, "site_ruby") elsif $sitedir !~ Regexp.quote(version) $sitedir = File.join($sitedir, version) end end if (destdir = ENV['DESTDIR']) $sitedir = destdir + $sitedir File::makedirs($sitedir) end flexmock_dest = File.join($sitedir, "flexmock") File::makedirs(flexmock_dest, true) File::chmod(0755, flexmock_dest) # The library files file = 'flexmock.rb' indir('lib') do Dir['**/*.rb'].each do |file| File::install( file, File.join($sitedir, file), 0644, true) end end flexmock-2.0.4/lib/000077500000000000000000000000001263476550700141125ustar00rootroot00000000000000flexmock-2.0.4/lib/flexmock.rb000066400000000000000000000004761263476550700162560ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/base' flexmock-2.0.4/lib/flexmock/000077500000000000000000000000001263476550700157225ustar00rootroot00000000000000flexmock-2.0.4/lib/flexmock/argument_matchers.rb000077500000000000000000000042771263476550700217740ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' class FlexMock #################################################################### # Match any object class AnyMatcher def ===(target) true end def inspect "ANY" end end #################################################################### # Match only things that are equal. class EqualMatcher def initialize(obj) @obj = obj end def ===(target) @obj == target end def inspect "==(#{@obj.inspect})" end end ANY = AnyMatcher.new #################################################################### # Match only things where the block evaluates to true. class ProcMatcher def initialize(&block) @block = block end def ===(target) @block.call(target) end def inspect "on{...}" end end #################################################################### # Match hashes that match all the fields of +hash+. class HashMatcher def initialize(hash) @hash = hash end def ===(target) @hash.all? { |k, v| target[k] == v } end def inspect "hsh(#{@hash.inspect})" end end #################################################################### # Match objects that implement all the methods in +methods+. class DuckMatcher def initialize(methods) @methods = methods end def ===(target) @methods.all? { |m| target.respond_to?(m) } end def inspect "ducktype(#{@methods.map{|m| m.inspect}.join(',')})" end end #################################################################### # Match objects that implement all the methods in +methods+. class OptionalProcMatcher def initialize end def ===(target) ArgumentMatching.missing?(target) || Proc === target end def inspect "optional_proc" end end OPTIONAL_PROC_MATCHER = OptionalProcMatcher.new end flexmock-2.0.4/lib/flexmock/argument_matching.rb000066400000000000000000000014611263476550700217450ustar00rootroot00000000000000class FlexMock module ArgumentMatching module_function MISSING_ARG = Object.new def all_match?(expected_args, actual_args) return true if expected_args.nil? return false if actual_args.size > expected_args.size i = 0 while i < actual_args.size return false unless match?(expected_args[i], actual_args[i]) i += 1 end while i < expected_args.size return false unless match?(expected_args[i], MISSING_ARG) i += 1 end true end # Does the expected argument match the corresponding actual value. def match?(expected, actual) expected === actual || expected == actual || ( Regexp === expected && expected === actual.to_s ) end def missing?(arg) arg == MISSING_ARG end end end flexmock-2.0.4/lib/flexmock/argument_types.rb000077500000000000000000000026411263476550700213230ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/argument_matchers' class FlexMock # Include this module in your test class if you wish to use the +eq+ # and +any+ argument matching methods without a prefix. (Otherwise # use FlexMock.any and FlexMock.eq(obj). # module ArgumentTypes # Return an argument matcher that matches any argument. def any ANY end # Return an argument matcher that only matches things equal to # (==) the given object. def eq(obj) EqualMatcher.new(obj) end # Return an argument matcher that matches any object, that when # passed to the supplied block, will cause the block to return # true. def on(&block) ProcMatcher.new(&block) end # Return an argument matcher that matches a hash with the given # entries. def hsh(hash) HashMatcher.new(hash) end # Return an argument matcher that matches any object that # implementes (i.e. responds to) the given method list. def ducktype(*methods) DuckMatcher.new(methods) end def optional_proc OPTIONAL_PROC_MATCHER end end extend ArgumentTypes end flexmock-2.0.4/lib/flexmock/base.rb000077500000000000000000000015321263476550700171650ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/symbol_extensions' require 'flexmock/object_extensions' require 'flexmock/class_extensions' require 'flexmock/core' require 'flexmock/default_framework_adapter' require 'flexmock/expectation_director' require 'flexmock/expectation' require 'flexmock/argument_matchers' require 'flexmock/argument_types' require 'flexmock/validators' require 'flexmock/recorder' require 'flexmock/mock_container' require 'flexmock/partial_mock' require 'flexmock/undefined' require 'flexmock/deprecated_methods' require 'flexmock/extensions/active_record_model' flexmock-2.0.4/lib/flexmock/call_record.rb000066400000000000000000000013561263476550700205250ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ class FlexMock CallRecord = Struct.new(:method_name, :args, :block_given, :expectation) do def matches?(sym, actual_args, options) method_name == sym && ArgumentMatching.all_match?(actual_args, args) && matches_block?(options[:with_block]) end private def matches_block?(block_option) block_option.nil? || (block_option && block_given) || (!block_option && !block_given) end end end flexmock-2.0.4/lib/flexmock/call_validator.rb000066400000000000000000000033221263476550700212270ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ class FlexMock # A CallValidator checks the list of call records for a particular # method name and arguments. class CallValidator # Does the +calls+ list record a method named +method_name+ with # +args+. Options include: # # * :times => n -- If given, the call should match exactly +n+ times. # * :and => [] -- A list of argument validations to be run on each # matching invocation. # * :on_count => n -- If given, the :and validations on only run on the # nth invocation. # def received?(calls, method_name, args, options) count = 0 calls.each { |call_record| if call_record.matches?(method_name, args, options) count += 1 run_additional_validations(call_record, count, options) end } count_matches?(count, options[:times]) end private def additionals(options) ands = options[:and] if ands.nil? [] elsif ands.is_a?(Proc) [ands] else ands end end def run_additional_validations(call_record, count, options) if options[:on_count].nil? || count == options[:on_count] additionals(options).each do |add| add.call(*call_record.args) end end end def count_matches?(count, times) if times count == times else count > 0 end end end end flexmock-2.0.4/lib/flexmock/class_extensions.rb000066400000000000000000000011271263476550700216340ustar00rootroot00000000000000# Detecting whether a class has a definition for a method or not # changes between Ruby 1.8 and Ruby 1.9. We introduce the # "flexmock_defined?" method on class objects to have a portable way # to determine that. # # NOTE: responds_to? isn't appropriate. We don't care if the object # responds to the method or not. We want to know if the class # has a definition for the method. A subtle difference. # class Class # Does a class directly define a method named "method_name"? def flexmock_defined?(method_name) instance_methods.include?(method_name.flexmock_as_name) end end flexmock-2.0.4/lib/flexmock/composite_expectation.rb000066400000000000000000000027471263476550700226660ustar00rootroot00000000000000class FlexMock # A composite expectation allows several expectations to be grouped into a # single composite and then apply the same constraints to all expectations # in the group. class CompositeExpectation # Initialize the composite expectation. def initialize @expectations = [] end # Add an expectation to the composite. def add(expectation) @expectations << expectation end # Apply the constraint method to all expectations in the composite. def method_missing(sym, *args, &block) @expectations.each do |expectation| expectation.send(sym, *args, &block) end self end # The following methods return a value, so we make an arbitrary choice # and return the value for the first expectation in the composite. # Return the order number of the first expectation in the list. def order_number @expectations.first.order_number end # Return the associated mock object. def mock @expectations.first.mock end # Start a new method expectation. The following constraints will be # applied to the new expectation. def should_receive(*args, &block) @expectations.first.mock. flexmock_define_expectation(caller, *args, &block) end # Return a string representations def to_s if @expectations.size > 1 "[" + @expectations.collect { |e| e.to_s }.join(', ') + "]" else @expectations.first.to_s end end end end flexmock-2.0.4/lib/flexmock/core.rb000077500000000000000000000174221263476550700172100ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/errors' require 'flexmock/ordering' require 'flexmock/argument_matching' require 'flexmock/explicit_needed' require 'flexmock/class_extensions' require 'flexmock/expectation_builder' require 'flexmock/call_validator' require 'flexmock/call_record' # FlexMock is a flexible mock object framework for creating and using # test doubles (mocks, stubs and spies). # # Basic Usage: # # m = flexmock("name") # m.should_receive(:upcase).with("stuff"). # and_return("STUFF") # m.should_receive(:downcase).with(String). # and_return { |s| s.downcase }.once # # With Test::Unit Integration: # # class TestSomething < Test::Unit::TestCase # def test_something # m = flexmock("name") # m.should_receive(:hi).and_return("Hello") # m.hi # end # end # # Note: Also, if you override +teardown+, make sure you call +super+. # class FlexMock include Ordering attr_reader :flexmock_name attr_accessor :flexmock_container class << self attr_accessor :partials_are_based end self.partials_are_based = false # Create a FlexMock object with the given name. The name is used in # error messages. If no container is given, create a new, one-off # container for this mock. def initialize(name="unknown", container=nil) @flexmock_name = name @expectations = Hash.new @ignore_missing = false @verified = false @calls = [] @base_class = nil container = UseContainer.new if container.nil? container.flexmock_remember(self) end # Return the inspection string for a mock. def inspect "" end # Verify that each method that had an explicit expected count was # actually called that many times. def flexmock_verify return if @verified @verified = true flexmock_wrap do @expectations.each do |sym, handler| handler.flexmock_verify end end end # Teardown and infrastructure setup for this mock. def flexmock_teardown @flexmock_closed = true end def flexmock_closed? @flexmock_closed end # Ignore all undefined (missing) method calls. def should_ignore_missing @ignore_missing = true self end alias mock_ignore_missing should_ignore_missing def by_default @last_expectation.by_default self end # Handle missing methods by attempting to look up a handler. def method_missing(sym, *args, &block) FlexMock.verify_mocking_allowed! enhanced_args = block_given? ? args + [block] : args call_record = CallRecord.new(sym, enhanced_args, block_given?) @calls << call_record flexmock_wrap do if flexmock_closed? FlexMock.undefined elsif handler = @expectations[sym] handler.call(enhanced_args, call_record) elsif @base_class && @base_class.flexmock_defined?(sym) FlexMock.undefined elsif @ignore_missing FlexMock.undefined else super(sym, *args, &block) end end end # Save the original definition of respond_to? for use a bit later. alias flexmock_respond_to? respond_to? # Override the built-in respond_to? to include the mocked methods. def respond_to?(sym, *args) super || (@expectations[sym] ? true : @ignore_missing) end # Find the mock expectation for method sym and arguments. def flexmock_find_expectation(method_name, *args) # :nodoc: exp = @expectations[method_name] exp ? exp.find_expectation(*args) : nil end # Return the expectation director for a method name. def flexmock_expectations_for(method_name) # :nodoc: @expectations[method_name] end def flexmock_based_on(base_class) @base_class = base_class if base_class <= Kernel should_receive(:class => base_class) should_receive(:kind_of?).and_return { |against| base_class <= against } end end CALL_VALIDATOR = CallValidator.new # True if the mock received the given method and arguments. def flexmock_received?(method_name, args, options={}) CALL_VALIDATOR.received?(@calls, method_name, args, options) end # Return the list of calls made on this mock. Used in formatting # error messages. def flexmock_calls @calls end # Invocke the original non-mocked functionality for the given # symbol. def flexmock_invoke_original(method_name, args) return FlexMock.undefined end # Override the built-in +method+ to include the mocked methods. def method(method_name) @expectations[method_name] || super rescue NameError => ex if @ignore_missing proc { FlexMock.undefined } else raise ex end end # :call-seq: # mock.should_receive(:method_name) # mock.should_receive(:method1, method2, ...) # mock.should_receive(:meth1 => result1, :meth2 => result2, ...) # # Declare that the mock object should receive a message with the given name. # # If more than one method name is given, then the mock object should expect # to receive all the listed melthods. If a hash of method name/value pairs # is given, then the each method will return the associated result. Any # expectations applied to the result of +should_receive+ will be applied to # all the methods defined in the argument list. # # An expectation object for the method name is returned as the result of # this method. Further expectation constraints can be added by chaining to # the result. # # See Expectation for a list of declarators that can be used. # def should_receive(*args) flexmock_define_expectation(caller, *args) end # Using +location+, define the expectations specified by +args+. def flexmock_define_expectation(location, *args) @last_expectation = EXP_BUILDER.parse_should_args(self, args) do |method_name| @expectations[method_name] ||= ExpectationDirector.new(method_name) result = Expectation.new(self, method_name, location) @expectations[method_name] << result override_existing_method(method_name) if flexmock_respond_to?(method_name) result = ExplicitNeeded.new(result, method_name, @base_class) if @base_class && ! @base_class.flexmock_defined?(method_name) result end end # Declare that the mock object should expect methods by providing a # recorder for the methods and having the user invoke the expected # methods in a block. Further expectations may be applied the # result of the recording call. # # Example Usage: # # mock.should_expect do |record| # record.add(Integer, 4) { |a, b| # a + b # }.at_least.once # def should_expect yield Recorder.new(self) end private # Wrap a block of code so the any assertion errors are wrapped so # that the mock name is added to the error message . def flexmock_wrap(&block) yield rescue FlexMock.framework_adapter.assertion_failed_error, FlexMock.framework_adapter.check_failed_error => ex raise ex, "in mock '#{@flexmock_name}': #{ex.message}", ex.backtrace end # Override the existing definition of method +method_name+ in the # mock. Most methods depend on the method_missing trick to be # invoked. However, if the method already exists, it will not call # method_missing. This method defines a singleton method on the mock # to explicitly invoke the method_missing logic. def override_existing_method(method_name) sclass.class_eval <<-EOS def #{method_name}(*args, &block) method_missing(:#{method_name}, *args, &block) end EOS end # Return the singleton class of the mock object. def sclass class << self; self; end end end require 'flexmock/core_class_methods' flexmock-2.0.4/lib/flexmock/core_class_methods.rb000077500000000000000000000070371263476550700221210ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' require 'flexmock/mock_container' class FlexMock class << self attr_reader :framework_adapter # Class method to make sure that verify is called at the end of a # test. One mock object will be created for each name given to # the use method. The mocks will be passed to the block as # arguments. If no names are given, then a single anonymous mock # object will be created. # # At the end of the use block, each mock object will be verified # to make sure the proper number of calls have been made. # # Usage: # # FlexMock.use("name") do |mock| # Creates a mock named "name" # mock.should_receive(:meth). # returns(0).once # end # mock is verified here # # NOTE: If you include FlexMock::TestCase into your test case # file, you can create mocks that will be automatically verified in # the test teardown by using the +flexmock+ method. # def use(*names) names = ["unknown"] if names.empty? container = UseContainer.new mocks = names.collect { |n| container.flexmock(n) } yield(*mocks) rescue Exception => _ container.got_exception = true raise ensure container.flexmock_teardown end FORBID_MOCKING = :__flexmock_forbid_mocking # Forbid mock calls to happen while the block is being evaluated # # @param [Object] mocking_forbidden_return the return value that should be # used if a mocking call has happened. If no mocking calls happened, # returns the return value of the block def forbid_mocking(mocking_forbidden_return = nil) current, Thread.current[FORBID_MOCKING] = Thread.current[FORBID_MOCKING], true catch(FORBID_MOCKING) do return yield end mocking_forbidden_return ensure Thread.current[FORBID_MOCKING] = current end # Verify that mocking is allowed in the current context. Throws if it is # not. def verify_mocking_allowed! if Thread.current[FORBID_MOCKING] throw FORBID_MOCKING end end # Class method to format a method name and argument list as a nice # looking string. def format_call(sym, args) # :nodoc: "#{sym}(#{format_args(args)})" end # Class method to format a list of args (the part between the # parenthesis). def format_args(args) if args args = args.map do |a| FlexMock.forbid_mocking("") do a.inspect end end args.join(', ') else "*args" end end # Check will assert the block returns true. If it doesn't, an # assertion failure is triggered with the given message. def check(msg, &block) # :nodoc: if FlexMock.framework_adapter.respond_to?(:check) FlexMock.framework_adapter.check(msg, &block) else FlexMock.framework_adapter.make_assertion(msg, &block) end end end # Container object to be used by the FlexMock.use method. class UseContainer include MockContainer attr_accessor :got_exception def initialize @got_exception = false end def passed? ! got_exception end end end flexmock-2.0.4/lib/flexmock/default_framework_adapter.rb000077500000000000000000000013211263476550700234500ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' class FlexMock class DefaultFrameworkAdapter def make_assertion(msg, &block) unless yield msg = msg.call if msg.is_a?(Proc) fail assertion_failed_error, msg end end def check(msg, &block) make_assertion(msg, &block) end class AssertionFailedError < StandardError; end def assertion_failed_error AssertionFailedError end end end flexmock-2.0.4/lib/flexmock/deprecated_methods.rb000066400000000000000000000035141263476550700220750ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ class Module def flexmock_deprecate(*method_names) method_names.each do |method_name| eval_line = __LINE__ + 1 module_eval %{ def #{method_name}(*args) $stderr.puts "#{method_name} is deprecated, use flex#{method_name} instead" flex#{method_name}(*args) end }, __FILE__, eval_line end end end # Deprecated Methods # ================== # # The following methods are no longer supported in FlexMock. Include # this file for legacy applications. # class FlexMock # Handle all messages denoted by +sym+ by calling the given block # and passing any parameters to the block. If we know exactly how # many calls are to be made to a particular method, we may check # that by passing in the number of expected calls as a second # paramter. def mock_handle(sym, expected_count=nil, &block) # :nodoc: $stderr.puts "mock_handle is deprecated, " + "use the new should_receive interface instead." self.should_receive(sym).times(expected_count).returns(&block) end flexmock_deprecate :mock_verify, :mock_teardown, :mock_wrap class PartialMockProxy MOCK_METHODS << :any_instance # any_instance is present for backwards compatibility with version 0.5.0. # @deprecated def any_instance(&block) $stderr.puts "any_instance is deprecated, use new_instances instead." new_instances(&block) end end module Ordering flexmock_deprecate( :mock_allocate_order, :mock_groups, :mock_current_order, :mock_validate_order) end end flexmock-2.0.4/lib/flexmock/errors.rb000066400000000000000000000007351263476550700175700ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' class FlexMock # Error raised when flexmock is used incorrectly. class UsageError < ::RuntimeError end class MockError < ::RuntimeError end end flexmock-2.0.4/lib/flexmock/expectation.rb000077500000000000000000000326711263476550700206060ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' require 'flexmock/argument_matching' require 'flexmock/expectation_recorder' class FlexMock # An Expectation is returned from each +should_receive+ message sent # to mock object. Each expectation records how a message matching # the message name (argument to +should_receive+) and the argument # list (given by +with+) should behave. Mock expectations can be # recorded by chaining the declaration methods defined in this # class. # # For example: # # mock.should_receive(:meth).with(args).and_returns(result) # class Expectation attr_reader :expected_args, :order_number attr_accessor :mock # Create an expectation for a method named +sym+. def initialize(mock, sym, location) @mock = mock @sym = sym @location = location @expected_args = nil @count_validators = [] @count_validator_class = ExactCountValidator @actual_count = 0 @return_value = nil @return_queue = [] @yield_queue = [] @order_number = nil @global_order_number = nil @globally = nil end def to_s FlexMock.format_call(@sym, @expected_args) end # Return a description of the matching features of the # expectation. Matching features include: # # * name of the method # * argument matchers # * call count validators # def description result = "should_receive(#{@sym.inspect})" result << ".with(#{FlexMock.format_args(@expected_args)})" if @expected_args @count_validators.each do |validator| result << validator.describe end result end # Validate that this expectation is eligible for an extra call def validate_eligible @count_validators.each do |v| if !v.eligible?(@actual_count) v.validate(@actual_count + 1) end end rescue CountValidator::ValidationFailed => e FlexMock.framework_adapter.check(e.message) { false } end # Verify the current call with the given arguments matches the # expectations recorded in this object. def verify_call(*args) validate_eligible validate_order @actual_count += 1 perform_yielding(args) return_value(args) end # Public return value (odd name to avoid accidental use as a # constraint). def _return_value(args) # :nodoc: return_value(args) end # Find the return value for this expectation. (private version) def return_value(args) case @return_queue.size when 0 block = lambda { |*a| @return_value } when 1 block = @return_queue.first else block = @return_queue.shift end block.call(*args) end private :return_value # Yield stored values to any blocks given. def perform_yielding(args) @return_value = nil unless @yield_queue.empty? block = args.last values = (@yield_queue.size == 1) ? @yield_queue.first : @yield_queue.shift if block && block.respond_to?(:call) @return_value = block.call(*values) else fail MockError, "No Block given to mock with 'and_yield' expectation" end end end private :perform_yielding # Is this expectation eligible to be called again? It is eligible # only if all of its count validators agree that it is eligible. def eligible? @count_validators.all? { |v| v.eligible?(@actual_count) } end # Is this expectation constrained by any call counts? def call_count_constrained? ! @count_validators.empty? end # Validate that the order def validate_order if @order_number @mock.flexmock_validate_order( to_s, @order_number, SpyDescribers.describe_calls(@mock)) end if @global_order_number @mock.flexmock_container.flexmock_validate_order( to_s, @global_order_number, SpyDescribers.describe_calls(@mock)) end end private :validate_order # Validate the correct number of calls have been made. Called by # the teardown process. def flexmock_verify @count_validators.each do |v| v.validate(@actual_count) end rescue CountValidator::ValidationFailed => e FlexMock.framework_adapter.make_assertion(e.message, @location) { false } end # Does the argument list match this expectation's argument # specification. def match_args(args) ArgumentMatching.all_match?(@expected_args, args) end # Declare that the method should expect the given argument list. def with(*args) @expected_args = args self end # Declare that the method should be called with no arguments. def with_no_args with end # Declare that the method can be called with any number of # arguments of any type. def with_any_args @expected_args = nil self end # :call-seq: # and_return(value) # and_return(value, value, ...) # and_return { |*args| code } # # Declare that the method returns a particular value (when the # argument list is matched). # # * If a single value is given, it will be returned for all matching # calls. # * If multiple values are given, each value will be returned in turn for # each successive call. If the number of matching calls is greater # than the number of values, the last value will be returned for # the extra matching calls. # * If a block is given, it is evaluated on each call and its # value is returned. # # For example: # # mock.should_receive(:f).returns(12) # returns 12 # # mock.should_receive(:f).with(String). # returns an # returns { |str| str.upcase } # upcased string # # +returns+ is an alias for +and_return+. # def and_return(*args, &block) if block_given? @return_queue << block else args.each do |arg| @return_queue << lambda { |*a| arg } end end self end alias :returns :and_return # :nodoc: # Declare that the method returns and undefined object # (FlexMock.undefined). Since the undefined object will always # return itself for any message sent to it, it is a good "I don't # care" value to return for methods that are commonly used in # method chains. # # For example, if m.foo returns the undefined object, then: # # m.foo.bar.baz # # returns the undefined object without throwing an exception. # def and_return_undefined and_return(FlexMock.undefined) end alias :returns_undefined :and_return_undefined # :call-seq: # and_yield(value1, value2, ...) # # Declare that the mocked method is expected to be given a block # and that the block will be called with the values supplied to # yield. If the mock is called multiple times, mulitple # and_yield declarations can be used to supply different # values on each call. # # An error is raised if the mocked method is not called with a # block. def and_yield(*yield_values) @yield_queue << yield_values end alias :yields :and_yield # :call-seq: # and_raise(an_exception) # and_raise(SomeException) # and_raise(SomeException, args, ...) # # Declares that the method will raise the given exception (with # an optional message) when executed. # # * If an exception instance is given, then that instance will be # raised. # # * If an exception class is given, the exception raised with be # an instance of that class constructed with +new+. Any # additional arguments in the argument list will be passed to # the +new+ constructor when it is invoked. # # +raises+ is an alias for +and_raise+. # def and_raise(exception, *args) and_return { raise exception, *args } end alias :raises :and_raise # :call-seq: # and_throw(a_symbol) # and_throw(a_symbol, value) # # Declares that the method will throw the given symbol (with an # optional value) when executed. # # +throws+ is an alias for +and_throw+. # def and_throw(sym, value=nil) and_return { throw sym, value } end alias :throws :and_throw def pass_thru(&block) block ||= lambda { |value| value } and_return { |*args| begin block.call(@mock.flexmock_invoke_original(@sym, args)) rescue NoMethodError => e if e.name == @sym raise e, "#{e.message} while performing #pass_thru in expectation object #{self}" else raise end end } end # Declare that the method may be called any number of times. def zero_or_more_times at_least.never end # Declare that the method is called +limit+ times with the # declared argument list. This may be modified by the +at_least+ # and +at_most+ declarators. def times(limit) @count_validators << @count_validator_class.new(self, limit) unless limit.nil? @count_validator_class = ExactCountValidator self end # Declare that the method is never expected to be called with the # given argument list. This may be modified by the +at_least+ and # +at_most+ declarators. def never times(0) end # Declare that the method is expected to be called exactly once # with the given argument list. This may be modified by the # +at_least+ and +at_most+ declarators. def once times(1) end # Declare that the method is expected to be called exactly twice # with the given argument list. This may be modified by the # +at_least+ and +at_most+ declarators. def twice times(2) end # Modifies the next call count declarator (+times+, +never+, # +once+ or +twice+) so that the declarator means the method is # called at least that many times. # # E.g. method f must be called at least twice: # # mock.should_receive(:f).at_least.twice # def at_least @count_validator_class = AtLeastCountValidator self end # Modifies the next call count declarator (+times+, +never+, # +once+ or +twice+) so that the declarator means the method is # called at most that many times. # # E.g. method f must be called no more than twice # # mock.should_receive(:f).at_most.twice # def at_most @count_validator_class = AtMostCountValidator self end # Declare that the given method must be called in order. All # ordered method calls must be received in the order specified by # the ordering of the +should_receive+ messages. Receiving a # methods out of the specified order will cause a test failure. # # If the user needs more fine control over ordering # (e.g. specifying that a group of messages may be received in any # order as long as they all come after another group of messages), # a _group_ _name_ may be specified in the +ordered+ calls. All # messages within the same group may be received in any order. # # For example, in the following, messages +flip+ and +flop+ may be # received in any order (because they are in the same group), but # must occur strictly after +start+ but before +end+. The message # +any_time+ may be received at any time because it is not # ordered. # # m = FlexMock.new # m.should_receive(:any_time) # m.should_receive(:start).ordered # m.should_receive(:flip).ordered(:flip_flop_group) # m.should_receive(:flop).ordered(:flip_flop_group) # m.should_receive(:end).ordered # def ordered(group_name=nil) if @globally @global_order_number = define_ordered(group_name, @mock.flexmock_container) else @order_number = define_ordered(group_name, @mock) end @globally = false self end # Modifier that changes the next ordered constraint to apply # globally across all mock objects in the container. def globally @globally = true self end # Helper method for defining ordered expectations. def define_ordered(group_name, ordering) if ordering.nil? fail UsageError, "Mock #{@mock.flexmock_name} " + "is not in a container and cannot be globally ordered." end if group_name.nil? result = ordering.flexmock_allocate_order elsif (num = ordering.flexmock_groups[group_name]) result = num else result = ordering.flexmock_allocate_order ordering.flexmock_groups[group_name] = result end result end private :define_ordered # No-op for allowing explicit calls when explicit not explicitly # needed. def explicitly self end def by_default expectations = mock.flexmock_expectations_for(@sym) expectations.defaultify_expectation(self) if expectations end def flexmock_location_filter yield rescue Exception => ex bt = @location.dup flexmock_dir = File.expand_path(File.dirname(__FILE__)) while bt.first.start_with?(flexmock_dir) bt.shift end raise ex, ex.message, bt end end end flexmock-2.0.4/lib/flexmock/expectation_builder.rb000066400000000000000000000105141263476550700223010ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/composite_expectation' class FlexMock class ExpectationBuilder # :call-seq: # parse_should_args(args) { |symbol| ... } # # This method provides common handling for the various should_receive # argument lists. It sorts out the differences between symbols, arrays and # hashes, and identifies the method names specified by each. As each # method name is identified, create a mock expectation for it using the # supplied block. def parse_should_args(mock, args, &block) # :nodoc: result = CompositeExpectation.new args.each do |arg| case arg when Hash arg.each do |k,v| exp = create_expectation(mock, k, &block).and_return(v) result.add(exp) end when Symbol, String result.add(create_expectation(mock, arg, &block)) end end result end # Create an expectation for the name on this mock. For simple # mocks, this is done by calling the provided block parameter and # letting the calling site handle the creation of the expectation # (which differs between full mocks and partial mocks). # # If the name_chain contains demeter mocking chains, then the # process is more complex. A series of mocks are created, each # component of the chain returning the next mock until the # expectation for the last component is returned. def create_expectation(mock, name_chain, &block) names = name_chain.to_s.split('.').map { |n| n.to_sym } check_method_names(names) if names.size == 1 block.call(names.first) elsif names.size > 1 create_demeter_chain(mock, names) else fail "Empty list of names" end end # Build the chain of mocks for demeter style mocking. # # This method builds a chain of mocks to support demeter style # mocking. Given a mock chain of "first.second.third.last", we # must build a chain of mock methods that return the next mock in # the chain. The expectation for the last method of the chain is # returned as the result of the method. # # Things to consider: # # * The expectations for all methods but the last in the chain # will be setup to expect no parameters and to return the next # mock in the chain. # # * It could very well be the case that several demeter chains # will be defined on a single mock object, and those chains # could share some of the same methods (e.g. "mock.one.two.read" # and "mock.one.two.write" both share the methods "one" and # "two"). It is important that the shared methods return the # same mocks in both chains. # def create_demeter_chain(mock, names) container = mock.flexmock_container last_method = names.pop names.each do |name| exp = mock.flexmock_find_expectation(name) if exp next_mock = exp._return_value([]) check_proper_mock(next_mock, name) else next_mock = container.flexmock("demeter_#{name}") mock.should_receive(name).and_return(next_mock) end mock = next_mock end mock.should_receive(last_method) end # Check that the given mock is a real FlexMock mock. def check_proper_mock(mock, method_name) unless mock.respond_to?(:should_receive) fail FlexMock::UsageError, "Conflicting mock declaration for '#{method_name}' in demeter style mock" end end METHOD_NAME_ALTS = [ '[A-Za-z_][A-Za-z0-9_]*[=!?]?', '\[\]=?', '\*\\*', '<<', '>>', '<=>', '[<>=!]=', '[=!]~', '===', '[-+]@', '[-+\*\/%&^|<>~`!]' ].join("|") METHOD_NAME_RE = /^(#{METHOD_NAME_ALTS})$/ # Check that all the names in the list are valid method names. def check_method_names(names) names.each do |name| fail FlexMock::UsageError, "Ill-formed method name '#{name}'" if name.to_s !~ METHOD_NAME_RE end end end EXP_BUILDER = ExpectationBuilder.new end flexmock-2.0.4/lib/flexmock/expectation_director.rb000077500000000000000000000051771263476550700225020ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' require 'flexmock/errors' class FlexMock # The expectation director is responsible for routing calls to the # correct expectations for a given argument list. # class ExpectationDirector # Create an ExpectationDirector for a mock object. def initialize(sym) @sym = sym @expectations = [] @defaults = [] @expected_order = nil end # Invoke the expectations for a given set of arguments. # # First, look for an expectation that matches the arguments and # is eligible to be called. Failing that, look for a expectation # that matches the arguments (at this point it will be ineligible, # but at least we will get a good failure message). Finally, # check for expectations that don't have any argument matching # criteria. def call(args, call_record=nil) exp = find_expectation(*args) call_record.expectation = exp if call_record FlexMock.check( proc { "no matching handler found for " + FlexMock.format_call(@sym, args) } ) { !exp.nil? } returned_value = exp.verify_call(*args) returned_value end # Append an expectation to this director. def <<(expectation) @expectations << expectation end # Find an expectation matching the given arguments. def find_expectation(*args) # :nodoc: if @expectations.empty? find_expectation_in(@defaults, *args) else find_expectation_in(@expectations, *args) end end # Do the post test verification for this director. Check all the # expectations. Only check the default expecatations if there are # no non-default expectations. def flexmock_verify # :nodoc: (@expectations.empty? ? @defaults : @expectations).each do |exp| exp.flexmock_verify end end # Move the last defined expectation a default. def defaultify_expectation(exp) # :nodoc: last_exp = @expectations.last if last_exp != exp fail UsageError, "Cannot make a previously defined expection into a default" end @expectations.pop @defaults << exp end private def find_expectation_in(expectations, *args) expectations.find { |e| e.match_args(args) && e.eligible? } || expectations.find { |e| e.match_args(args) } end end end flexmock-2.0.4/lib/flexmock/expectation_recorder.rb000066400000000000000000000021241263476550700224560ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ class FlexMock # An expectation recorder records any expectations received and plays them # back on demand. This is used to collect the expectations in the blockless # version of the new_instances call. # class ExpectationRecorder # Initialize the recorder. def initialize @expectations = [] end # Save any incoming messages to be played back later. def method_missing(sym, *args, &block) @expectations << [sym, args, block] self end # Apply the recorded messages to the given object in a chaining fashion # (i.e. the result of the previous call is used as the target of the next # call). def apply(mock) obj = mock @expectations.each do |sym, args, block| obj = obj.send(sym, *args, &block) end end end end flexmock-2.0.4/lib/flexmock/explicit_needed.rb000066400000000000000000000021521263476550700213740ustar00rootroot00000000000000 class FlexMock # Expectations on mocks with a base class can only be defined on # methods supported by the base class. Attempting to add an stub to # a method not defined on the base class will cause the expectation # to be wrapped in an ExplicitNeeded wrapper. The wrapper will throw # an exception unless the explicitly method is immediately called on # the expectation. # class ExplicitNeeded def initialize(expectation, method_name, base_class) @expectation = expectation @explicit = false @method_name = method_name @base_class = base_class end def explicitly @explicit = true self end def explicit? @explicit end def mock=(m) @expectation.mock = m end def method_missing(sym, *args, &block) if explicit? @expectation.send(sym, *args, &block) else fail NoMethodError, "Cannot stub methods not defined by the base class\n" + " Method: #{@method_name}\n" + " Base Class: #{@base_class}\n" + " (Use 'explicitly' to override)" end end end end flexmock-2.0.4/lib/flexmock/extensions/000077500000000000000000000000001263476550700201215ustar00rootroot00000000000000flexmock-2.0.4/lib/flexmock/extensions/active_record_model.rb000066400000000000000000000074251263476550700244470ustar00rootroot00000000000000require 'flexmock/mock_container' class FlexMock module Extensions class ActiveRecordModel # Handle the argument list. # # This method is called whenever an unrecognized symbol is # detected in the flexmock argument list. If the extension class # can handle it, it should return true. # # Extension data can be stored in the opts.data hash for later use # during the create and post_create phase. def handle(args, opts) return false unless args.first == :model args.shift opts.data[:model_class] = args.shift opts.extended = self true end # Create the test double. # # Create the custome test double according to the data from the # argument list. The object returned from this method is the # object returned from the original flexmock() method call. This # the returned object is NOT the actual mock object (which is the # case for things like partial proxies), then the opts.mock field # should be set to contain the actual mock object. def create(container, opts) id = next_id FlexMock.new("#{opts.data[:model_class]}_#{id}", container) end # Do any post-creation setup on the mock object. def post_create(opts, location) add_model_methods(opts.mock, opts.data[:model_class], location) end private # Return the next id for mocked models. def next_id @id_counter ||= 10000 @id_counter += 1 end def current_id @id_counter end # Automatically add mocks for some common methods in ActiveRecord # models. def add_model_methods(mock, model_class, location) add_model_methods_returning_values(mock, location, [:id, current_id ], [:to_params, current_id.to_s ], [:new_record?, false ], [:class, model_class ], [:errors, make_mock_model_errors_for(mock, location) ]) add_model_methods_with_behavior(mock, location, [:is_a?, lambda { |other| other == model_class } ], [:instance_of?, lambda { |other| other == model_class } ], [:kind_of?, lambda { |other| model_class.ancestors.include?(other) } ]) end def add_model_methods_returning_values(mock, location, *pairs) pairs.each do |method, retval| make_default_behavior(mock, location, method, retval) end end def add_model_methods_with_behavior(mock, location, *pairs) pairs.each do |method, block| make_default_behavior(mock, location, method, &block) end end # Create a mock model errors object (with default behavior). def make_mock_model_errors_for(mock, location) result = mock.flexmock_container.flexmock("errors") make_default_behavior(result, location, :count, 0) make_default_behavior(result, location, :full_messages, []) result end # Define default behavior on a mock object. # # If a block is given, use that to define the behavior. Otherwise # return the +retval+ value. def make_default_behavior(mock, location, method, retval=nil, &block) if block_given? mock.flexmock_define_expectation(location, method). with(FlexMock.any). and_return(&block). by_default else mock.flexmock_define_expectation(location, method). and_return(retval). by_default end end end FlexMock::CONTAINER_HELPER.add_extension(ActiveRecordModel.new) end end flexmock-2.0.4/lib/flexmock/minitest.rb000077500000000000000000000005651263476550700201140ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/minitest_integration' require 'flexmock/minitest_extensions' flexmock-2.0.4/lib/flexmock/minitest_extensions.rb000066400000000000000000000011071263476550700223610ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ begin # Minitest 5.0+ require 'minitest/test' class Minitest::Test include FlexMock::Minitest end rescue LoadError # Minitest < 5.0, as shipped with ruby at least up to 2.1 require 'minitest/unit' class MiniTest::Unit::TestCase include FlexMock::Minitest end end flexmock-2.0.4/lib/flexmock/minitest_integration.rb000077500000000000000000000047671263476550700225270ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ begin require 'minitest/assertions' rescue LoadError require 'minitest/unit' end require 'flexmock/base' require 'flexmock/test_unit_assert_spy_called' class FlexMock # Minitest::Test Integration. # # Include this module in any Test subclass (in test-style minitest) or or # describe block (in spec-style minitest) to get integration with FlexMock. # When this module is included, the mock container methods (e.g. flexmock(), # flexstub()) will be available. # module Minitest include ArgumentTypes include MockContainer include TestUnitAssertions # Teardown the test case, verifying any mocks that might have been # defined in this test case. def before_teardown super @flexmock_teardown_failure = nil if respond_to?(:capture_exceptions) capture_exceptions do flexmock_teardown end else begin flexmock_teardown rescue Exception => e @flexmock_teardown_failure = e end end end def after_teardown if @flexmock_teardown_failure raise @flexmock_teardown_failure end end end class CheckFailedError < RuntimeError; end # Adapter for adapting FlexMock to the Test::Unit framework. # class MinitestFrameworkAdapter if defined?(::Minitest) include ::Minitest::Assertions else include MiniTest::Assertions end attr_accessor :assertions def initialize @assertions = 0 end def filtered_backtrace(bt = caller) flexmock_dir = File.expand_path(File.dirname(__FILE__)) while bt.first.start_with?(flexmock_dir) bt.shift end bt end def make_assertion(msg, backtrace = caller, &block) backtrace = filtered_backtrace(backtrace) assert(yield, msg) rescue Exception => e e.set_backtrace backtrace raise e end def check(msg, &block) unless yield msg = msg.call if msg.is_a?(Proc) raise CheckFailedError, msg, filtered_backtrace end end def assertion_failed_error MiniTest::Assertion end def check_failed_error CheckFailedError end end @framework_adapter = MinitestFrameworkAdapter.new end flexmock-2.0.4/lib/flexmock/mock_builder.rb000066400000000000000000000073401263476550700207120ustar00rootroot00000000000000class FlexMock # This class contains helper methods for mock containers. Since # MockContainer is a module that is designed to be mixed into other # classes, (particularly testing framework test cases), we don't # want to pollute the method namespace of the class that mixes in # MockContainer. So we have aggressively moved a number of # MockContainer methods out of that class and into # MockBuilder to isoloate the names. # class MockBuilder def initialize(container) @container = container end def define_a_mock(location, *args, &block) opts = parse_creation_args(args) if opts.safe_mode && ! block_given? raise UsageError, "a block is required in safe mode" end result = create_double(opts) flexmock_mock_setup(opts.mock, opts, location, &block) run_post_creation_hooks(opts, location) result end FlexOpts = Struct.new( :name, :defs, :safe_mode, :mock, :domain_obj, :base_class, :extended, :extended_data ) do def data self.extended_data ||= {} end end # Parse the list of flexmock() arguments and populate the opts object. def parse_creation_args(args) opts = FlexOpts.new while ! args.empty? case args.first when Symbol unless parse_create_symbol(args, opts) opts.name = args.shift.to_s end when String, Symbol opts.name = args.shift.to_s when Hash opts.defs = args.shift when FlexMock opts.mock = args.shift else opts.domain_obj = args.shift end end set_base_class(opts) opts end # Create the test double based on the args options. def create_double(opts) if opts.extended result = opts.extended.create(container, opts) elsif opts.domain_obj result = create_partial(opts) else result = create_mock(opts) end opts.mock ||= result result end # Run any post creation hooks specified by an extension. def run_post_creation_hooks(opts, location) if opts.extended opts.extended.post_create(opts, location) end end # Setup the test double with its expections and such. def flexmock_mock_setup(mock, opts, location) mock.flexmock_based_on(opts.base_class) if opts.base_class mock.flexmock_define_expectation(location, opts.defs) yield(mock) if block_given? container.flexmock_remember(mock) end attr_reader :container private :container private # Set the base class if not defined and partials are based. def set_base_class(opts) if ! opts.base_class && opts.domain_obj && FlexMock.partials_are_based opts.base_class = opts.domain_obj.class end end # Handle a symbol in the flexmock() args list. def parse_create_symbol(args, opts) case args.first when :base, :safe opts.safe_mode = (args.shift == :safe) opts.domain_obj = args.shift when :on args.shift opts.base_class = args.shift opts.name ||= "#{opts.base_class} Mock" else CONTAINER_HELPER.extensions.each do |ext| handled = ext.handle(args, opts) return true if handled end return false end true end # Create a mock object in the options. def create_mock(opts) opts.mock ||= FlexMock.new(opts.name || "unknown", container) opts.mock end # Create a partial mock object in options. def create_partial(opts) opts.mock = PartialMockProxy.make_proxy_for( opts.domain_obj, container, opts.name, opts.safe_mode) opts.domain_obj end end end flexmock-2.0.4/lib/flexmock/mock_container.rb000077500000000000000000000130631263476550700212500ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' require 'flexmock/argument_types' require 'flexmock/ordering' require 'flexmock/mock_builder' class FlexMock # Mock container methods # # Include this module in to get integration with FlexMock. When this module # is included, mocks may be created with a simple call to the +flexmock+ # method. Mocks created with via the method call will automatically be # verified in the teardown of the test case. # module MockContainer include Ordering # Do the flexmock specific teardown stuff. If you need finer control, # you can use either +flexmock_verify+ or +flexmock_close+. def flexmock_teardown flexmock_verify unless flexmock_test_has_failed? ensure flexmock_close end # Perform verification on all mocks in the container. def flexmock_verify flexmock_created_mocks.each do |m| m.flexmock_verify end end # List of mocks created in this container def flexmock_created_mocks @flexmock_created_mocks ||= [] end # Close all the mock objects in the container. Closing a mock object # restores any original behavior that was displaced by the mock. def flexmock_close flexmock_created_mocks.each do |m| m.flexmock_teardown end @flexmock_created_mocks = [] end # Create a mocking object in the FlexMock framework. The +flexmock+ # method has a number of options available, depending on just what kind of # mocking object your require. Mocks created via +flexmock+ will be # automatically verify during the teardown phase of your test framework. # # :call-seq: # flexmock() { |mock| ... } # flexmock(name) { |mock| ... } # flexmock(expect_hash) { |mock| ... } # flexmock(name, expect_hash) { |mock| ... } # flexmock(real_object) { |mock| ... } # flexmock(real_object, name) { |mock| ... } # flexmock(real_object, name, expect_hash) { |mock| ... } # flexmock(:base, string, name, expect_hash) { |mock| ... } # # Note: A plain flexmock() call without a block will return the # mock object (the object that interprets should_receive and its # brethern). A flexmock() call that _includes_ a block will return the # domain objects (the object that will interpret domain messages) since # the mock will be passed to the block for configuration. With regular # mocks, this distinction is unimportant because the mock object and the # domain object are the same object. However, with partial mocks, the # mock object is separation from the domain object. Keep that distinciton # in mind. # # name :: # Name of the mock object. If no name is given, "unknown" is used for # full mocks and "flexmock(real_object)" is used for partial # mocks. # # expect_hash :: # Hash table of method names and values. Each method/value pair is # used to setup a simple expectation so that if the mock object # receives a message matching an entry in the table, it returns # the associated value. No argument our call count constraints are # added. Using an expect_hash is identical to calling: # # mock.should_receive(method_name).and_return(value) # # for each of the method/value pairs in the hash. # # real_object :: # If a real object is given, then a partial mock is constructed # using the real_object as a base. Partial mocks (formally referred # to as stubs) behave as a mock object when an expectation is matched, # and otherwise will behave like the original object. This is useful # when you want to use a real object for testing, but need to mock out # just one or two methods. # # :base :: # Forces the following argument to be used as the base of a # partial mock object. This explicit tag is only needed if you # want to use a string or a symbol as the mock base (string and # symbols would normally be interpretted as the mock name). # # &block :: # If a block is given, then the mock object is passed to the block and # expectations may be configured within the block. When a block is given # for a partial mock, flexmock will return the domain object rather than # the mock object. # def flexmock(*args, &block) @flexmock_worker ||= MockBuilder.new(self) @flexmock_worker.define_a_mock(caller, *args, &block) end alias flexstub flexmock # Remember the mock object / stub in the mock container. def flexmock_remember(mocking_object) @flexmock_created_mocks ||= [] @flexmock_created_mocks << mocking_object mocking_object.flexmock_container = self mocking_object end private # In frameworks (e.g. MiniTest) passed? will return nil to # indicate the test isn't over yet. From our point of view we are # only interested if the test has actually failed, so we wrap the # raw call to passed? and handle accordingly. def flexmock_test_has_failed? # :nodoc: passed? == false end end class ExtensionRegistry def add_extension(extension) extensions << extension end def extensions @extensions ||= [] end end CONTAINER_HELPER = ExtensionRegistry.new end flexmock-2.0.4/lib/flexmock/noop.rb000077500000000000000000000006411263476550700172260ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ # No-op include file. Used as a kludge so that only the comments in the # core.rb file are applied to the FlexMock class. flexmock-2.0.4/lib/flexmock/object_extensions.rb000066400000000000000000000002121263476550700217670ustar00rootroot00000000000000class Object def flexmock_singleton_defined?(method_name) singleton_methods(false).include?(method_name.flexmock_as_name) end end flexmock-2.0.4/lib/flexmock/ordering.rb000066400000000000000000000030741263476550700200640ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ class FlexMock # The ordering module contains the methods and data structures used # to determine proper orderring of mocked calls. By providing the # functionality in a module, a individual mock object can order its # own calls, and the container can provide ordering at a global # level. module Ordering # Allocate the next available order number. def flexmock_allocate_order @flexmock_allocated_order ||= 0 @flexmock_allocated_order += 1 end # Hash of groups defined in this ordering. def flexmock_groups @flexmock_groups ||= {} end # Current order number in this ordering. def flexmock_current_order @flexmock_current_order ||= 0 end # Set the current order for this ordering. def flexmock_current_order=(value) @flexmock_current_order = value end def flexmock_validate_order(method_name, order_number, calls_description = nil) msg = "method #{method_name} called out of order " + "(expected order #{order_number}, was #{flexmock_current_order})" if calls_description msg += "\n#{calls_description}" end FlexMock.check(msg) do order_number >= self.flexmock_current_order end self.flexmock_current_order = order_number end end end flexmock-2.0.4/lib/flexmock/partial_mock.rb000077500000000000000000000250321263476550700207210ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' require 'flexmock/expectation_builder' class FlexMock # PartialMockProxy is used to mate the mock framework to an existing # object. The object is "enhanced" with a reference to a mock object # (stored in @flexmock_proxy). When the +should_receive+ # method is sent to the proxy, it overrides the existing object's # method by creating singleton method that forwards to the mock. # When testing is complete, PartialMockProxy will erase the mocking # infrastructure from the object being mocked (e.g. remove instance # variables and mock singleton methods). # class PartialMockProxy include Ordering attr_reader :mock ProxyBox = Struct.new :proxy # Make a partial mock proxy and install it on the target +obj+. def self.make_proxy_for(obj, container, name, safe_mode) name ||= "flexmock(#{obj.class.to_s})" if ! proxy_defined_on?(obj) mock = FlexMock.new(name, container) proxy = PartialMockProxy.new(obj, mock, safe_mode) if obj.instance_variable_defined?("@flexmock_proxy") obj.instance_variable_get("@flexmock_proxy").proxy = proxy else obj.instance_variable_set("@flexmock_proxy", ProxyBox.new(proxy)) end end obj.instance_variable_get("@flexmock_proxy").proxy end # Is there a mock proxy defined on the domain object? def self.proxy_defined_on?(obj) obj.instance_variable_defined?("@flexmock_proxy") && obj.instance_variable_get("@flexmock_proxy").proxy end # The following methods are added to partial mocks so that they # can act like a mock. MOCK_METHODS = [ :should_receive, :new_instances, :should_receive_with_location, :flexmock_get, :flexmock_teardown, :flexmock_verify, :flexmock_received?, :flexmock_calls, :flexmock_find_expectation ] # Initialize a PartialMockProxy object. def initialize(obj, mock, safe_mode) @obj = obj @mock = mock @method_definitions = {} @methods_proxied = [] @proxy_definition_module = nil unless safe_mode add_mock_method(:should_receive) MOCK_METHODS.each do |sym| unless @obj.respond_to?(sym) add_mock_method(sym) end end end end # Get the mock object for the partial mock. def flexmock_get @mock end # :call-seq: # should_receive(:method_name) # should_receive(:method1, method2, ...) # should_receive(:meth1 => result1, :meth2 => result2, ...) # # Declare that the partial mock should receive a message with the given # name. # # If more than one method name is given, then the mock object should # expect to receive all the listed melthods. If a hash of method # name/value pairs is given, then the each method will return the # associated result. Any expectations applied to the result of # +should_receive+ will be applied to all the methods defined in the # argument list. # # An expectation object for the method name is returned as the result of # this method. Further expectation constraints can be added by chaining # to the result. # # See Expectation for a list of declarators that can be used. def should_receive(*args) flexmock_define_expectation(caller, *args) end def flexmock_define_expectation(location, *args) EXP_BUILDER.parse_should_args(self, args) do |method_name| unless @methods_proxied.include?(method_name) hide_existing_method(method_name) end ex = @mock.flexmock_define_expectation(location, method_name) ex.mock = self ex end end def flexmock_find_expectation(*args) @mock.flexmock_find_expectation(*args) end def add_mock_method(method_name) stow_existing_definition(method_name) proxy_module_eval do define_method(method_name) { |*args, &block| proxy = __flexmock_proxy or fail "Missing FlexMock proxy " + "(for method_name=#{method_name.inspect}, self=\#{self})" proxy.send(method_name, *args, &block) } end end # :call-seq: # new_instances.should_receive(...) # new_instances { |instance| instance.should_receive(...) } # # new_instances is a short cut method for overriding the behavior of any # new instances created via a mocked class object. # # By default, new_instances will mock the behaviour of the :new # method. If you wish to mock a different set of class methods, # just pass a list of symbols to as arguments. (previous versions # also mocked :allocate by default. If you need :allocate to be # mocked, just request it explicitly). # # For example, to stub only objects created by :make (and not # :new), use: # # flexmock(ClassName).new_instances(:make).should_receive(...) # def new_instances(*allocators, &block) fail ArgumentError, "new_instances requires a Class to stub" unless Class === @obj location = caller allocators = [:new] if allocators.empty? expectation_recorder = ExpectationRecorder.new allocators.each do |allocate_method| flexmock_define_expectation(location, allocate_method).and_return { |*args| create_new_mocked_object( allocate_method, args, expectation_recorder, block) } end expectation_recorder end # Create a new mocked object. # # The mocked object is created using the following steps: # (1) Allocate with the original allocation method (and args) # (2) Pass to the block for custom configuration. # (3) Apply any recorded expecations # def create_new_mocked_object(allocate_method, args, recorder, block) new_obj = flexmock_invoke_original(allocate_method, args) mock = flexmock_container.flexmock(new_obj) block.call(mock) unless block.nil? recorder.apply(mock) new_obj end private :create_new_mocked_object # Invoke the original definition of method on the object supported by # the stub. def flexmock_invoke_original(method, args) if original_method = @method_definitions[method] if Proc === args.last block = args.last args = args[0..-2] end original_method.bind(@obj).call(*args, &block) else @obj.__send__(:method_missing, method, *args, &block) end end # Verify that the mock has been properly called. After verification, # detach the mocking infrastructure from the existing object. def flexmock_verify @mock.flexmock_verify end # Remove all traces of the mocking framework from the existing object. def flexmock_teardown if ! detached? proxy_module_eval do methods = instance_methods(false).to_a methods.each do |m| remove_method m end end if @obj.instance_variable_defined?(:@flexmock_proxy) && (box = @obj.instance_variable_get(:@flexmock_proxy)) box.proxy = nil end @obj = nil end end # Forward to the mock's container. def flexmock_container @mock.flexmock_container end # Forward to the mock def flexmock_received?(*args) @mock.flexmock_received?(*args) end # Forward to the mock def flexmock_calls @mock.flexmock_calls end # Set the proxy's mock container. This set value is ignored # because the proxy always uses the container of its mock. def flexmock_container=(container) end # Forward the request for the expectation director to the mock. def flexmock_expectations_for(method_name) @mock.flexmock_expectations_for(method_name) end # Forward the based on request. def flexmock_based_on(*args) @mock.flexmock_based_on(*args) end private # The singleton class of the object. def target_singleton_class @obj.singleton_class end # Evaluate a block (or string) in the context of the singleton # class of the target partial object. def target_class_eval(*args, &block) target_singleton_class.class_eval(*args, &block) end # Evaluate a block into the module we use to define the proxy methods def proxy_module_eval(*args, &block) if !@proxy_definition_module obj = @obj @proxy_definition_module = m = Module.new do define_method(:__flexmock_proxy) do if box = obj.instance_variable_get(:@flexmock_proxy) box.proxy end end end target_class_eval { prepend m } end @proxy_definition_module.class_eval(*args, &block) end # Hide the existing method definition with a singleton defintion # that proxies to our mock object. If the current definition is a # singleton, we need to record the definition and remove it before # creating our own singleton method. If the current definition is # not a singleton, all we need to do is override it with our own # singleton. def hide_existing_method(method_name) stow_existing_definition(method_name) define_proxy_method(method_name) end # Stow the existing method definition so that it can be recovered # later. def stow_existing_definition(method_name) if !@methods_proxied.include?(method_name) @method_definitions[method_name] = target_class_eval { instance_method(method_name) } @methods_proxied << method_name end rescue NameError end # Define a proxy method that forwards to our mock object. The # proxy method is defined as a singleton method on the object # being mocked. def define_proxy_method(method_name) if method_name =~ /=$/ proxy_module_eval do define_method(method_name) do |*args, &block| __flexmock_proxy.mock.__send__(method_name, *args, &block) end end else proxy_module_eval <<-EOD def #{method_name}(*args, &block) FlexMock.verify_mocking_allowed! __flexmock_proxy.mock.#{method_name}(*args, &block) end EOD end end # Have we been detached from the existing object? def detached? @obj.nil? end end end flexmock-2.0.4/lib/flexmock/rails.rb000066400000000000000000000006321263476550700173620ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ # Require the modules needed for rails oriented mocking. require 'flexmock' require 'flexmock/rails/view_mocking' flexmock-2.0.4/lib/flexmock/recorder.rb000077500000000000000000000040151263476550700200570ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/argument_types' class FlexMock # Translate arbitrary method calls into expectations on the given # mock object. # class Recorder include FlexMock::ArgumentTypes # Create a method recorder for the mock +mock+. def initialize(mock) @mock = mock @strict = false end # Place the record in strict mode. While recording expectations # in strict mode, the following will be true. # # * All expectations will be expected in the order they were # recorded. # * All expectations will be expected once. # * All arguments will be placed in exact match mode, # including regular expressions and class objects. # # Strict mode is usually used when giving the recorder to a known # good algorithm. Strict mode captures the exact sequence of # calls and validate that the code under test performs the exact # same sequence of calls. # # The recorder may exit strict mode via a # should_be_strict(false) call. Non-strict expectations # may be recorded at that point, or even explicit expectations # (using +should_receieve+) can be specified. # def should_be_strict(is_strict=true) @strict = is_strict end # Is the recorder in strict mode? def strict? @strict end # Record an expectation for receiving the method +sym+ with the # given arguments. def method_missing(sym, *args, &block) expectation = @mock. flexmock_define_expectation(caller, sym). and_return(&block) if strict? args = args.collect { |arg| eq(arg) } expectation.with(*args).ordered.once else expectation.with(*args) end expectation end end end flexmock-2.0.4/lib/flexmock/rspec.rb000077500000000000000000000017131263476550700173700ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/base' class FlexMock if defined?(::RSpec) SpecModule = RSpec else SpecModule = Spec end class RSpecFrameworkAdapter def make_assertion(msg, &block) msg = msg.call if msg.is_a?(Proc) SpecModule::Expectations.fail_with(msg) unless yield end def check(msg, &block) make_assertion(msg, &block) end class AssertionFailedError < StandardError; end def assertion_failed_error SpecModule::Expectations::ExpectationNotMetError end def check_failed_error assertion_failed_error end end @framework_adapter = RSpecFrameworkAdapter.new end require 'flexmock/rspec_spy_matcher' flexmock-2.0.4/lib/flexmock/rspec/000077500000000000000000000000001263476550700170365ustar00rootroot00000000000000flexmock-2.0.4/lib/flexmock/rspec/configure.rb000066400000000000000000000004411263476550700213430ustar00rootroot00000000000000# Auto configure for RSpec # # Just require 'flexmock/rspec/configure' to automatically configure # RSpec to use flexmock. if defined?(RSpec) RSpec.configure do |config| config.mock_with :flexmock end else fail "Cannot auto-configure flexmock for ancient versions of rspec" end flexmock-2.0.4/lib/flexmock/rspec_spy_matcher.rb000066400000000000000000000034041263476550700217620ustar00rootroot00000000000000require 'flexmock/spy_describers' class FlexMock module RSpecMatchers class HaveReceived include SpyDescribers def initialize(method_name) @method_name = method_name @args = nil @block = nil @times = nil @needs_block = nil @additional_validations = [] end def matches?(spy) @spy = spy @options = construct_options @spy.flexmock_received?(@method_name, @args, @options) end def failure_message_for_should describe_spy_expectation(@spy, @method_name, @args, @options) end def failure_message_for_should_not describe_spy_negative_expectation(@spy, @method_name, @args, @options) end def description spy_description(@spy, @method_name, @args, @options) end def with(*args) @args = args self end def with_a_block @needs_block = true self end def without_a_block @needs_block = false self end def times(n) @times = n self end def never times(0) end def once times(1) end def twice times(2) end def on(on_count) @on_count = on_count self end def and(&block) @additional_validations << block self end def construct_options { :times => @times, :with_block => @needs_block, :on_count => @on_count, :and => @additional_validations, } end end def have_received(method_name) HaveReceived.new(method_name) end end end RSpec::configure do |config| config.include(FlexMock::RSpecMatchers) end flexmock-2.0.4/lib/flexmock/spy_describers.rb000066400000000000000000000042211263476550700212660ustar00rootroot00000000000000class FlexMock module SpyDescribers def spy_description(spy, sym, args, options) result = "have received " result << FlexMock.format_call(sym, args) result << times_description(options[:times]) result << block_description(options[:with_block]) result end def describe_spy_expectation(spy, sym, args, options={}) describe_spy(spy, sym, args, options) end def describe_spy_negative_expectation(spy, sym, args, options={}) describe_spy(spy, sym, args, options, " NOT") end def describe_spy(spy, sym, args, options, not_clause="") result = "expected " result << FlexMock.format_call(sym, args) result << " to#{not_clause} be received by " << spy.inspect result << times_description(options[:times]) result << block_description(options[:with_block]) result << ".\n" result << describe_calls(spy) result end def describe_calls(spy) result = '' if spy.flexmock_calls.empty? result << "No messages have been received\n" else result << "The following messages have been received:\n" spy.flexmock_calls.each do |call_record| append_call_record(result, call_record) end end result end def append_call_record(result, call_record) result << " " << FlexMock.format_call(call_record.method_name, call_record.args) if call_record.expectation result << " matched by " << call_record.expectation.description end result << "\n" end def times_description(times) case times when 0 " never" when 1 " once" when 2 " twice" when nil "" else " #{times} times" end end def block_description(needs_block) case needs_block when true " with a block" when false " without a block" else "" end end extend SpyDescribers end end flexmock-2.0.4/lib/flexmock/symbol_extensions.rb000066400000000000000000000003771263476550700220420ustar00rootroot00000000000000class Symbol case instance_methods.first when Symbol def flexmock_as_name self end when String def flexmock_as_name to_s end else fail "Unexpected class for method list #{instance_methods.first.class}" end end flexmock-2.0.4/lib/flexmock/test_unit.rb000077500000000000000000000006001263476550700202640ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/test_unit_integration' require 'flexmock/test_unit_testcase_extensions' flexmock-2.0.4/lib/flexmock/test_unit_assert_spy_called.rb000066400000000000000000000016231263476550700240470ustar00rootroot00000000000000require 'flexmock/spy_describers' class FlexMock module TestUnitAssertions include FlexMock::SpyDescribers def assert_spy_called(spy, method_name, *args) _assert_spy_called(false, spy, method_name, *args) end def assert_spy_not_called(spy, method_name, *args) _assert_spy_called(true, spy, method_name, *args) end private def _assert_spy_called(negative, spy, method_name, *args) options = {} if method_name.is_a?(Hash) options = method_name method_name = args.shift end args = nil if args == [:_] bool = spy.flexmock_received?(method_name, args, options) if negative bool = !bool message = describe_spy_negative_expectation(spy, method_name, args, options) else message = describe_spy_expectation(spy, method_name, args, options) end assert bool, message end end end flexmock-2.0.4/lib/flexmock/test_unit_integration.rb000077500000000000000000000037171263476550700227030ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test/unit/assertions' require 'flexmock/base' require 'flexmock/test_unit_assert_spy_called' class FlexMock # Test::Unit::TestCase Integration. # # Include this module in any TestCase class in a Test::Unit test # suite to get integration with FlexMock. When this module is # included, the mock container methods (e.g. flexmock(), flexstub()) # will be available. # # Note: If you define a +teardown+ method in the test case, # dont' forget to invoke the +super+ method! Failure to # invoke super will cause all mocks to not be verified. # module TestCase include ArgumentTypes include MockContainer include TestUnitAssertions # Teardown the test case, verifying any mocks that might have been # defined in this test case. def teardown super flexmock_teardown end end # Adapter for adapting FlexMock to the Test::Unit framework. # class TestUnitFrameworkAdapter include Test::Unit::Assertions attr_accessor :assertions def initialize @assertions = 0 end def make_assertion(msg, &block) unless yield msg = msg.call if msg.is_a?(Proc) assert(false, msg) end rescue assertion_failed_error => ex ex.message.sub!(/Expected block to return true value./,'') raise ex end def check(msg, &block) make_assertion(msg, &block) end def assertion_failed_error defined?(Test::Unit::AssertionFailedError) ? Test::Unit::AssertionFailedError : MiniTest::Assertion end def check_failed_error assertion_failed_error end end @framework_adapter = TestUnitFrameworkAdapter.new end flexmock-2.0.4/lib/flexmock/test_unit_testcase_extensions.rb000066400000000000000000000021661263476550700244440ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ class FlexMock module GenericTestCase def self.define_extensions_on(klass) klass.class_eval do include FlexMock::ArgumentTypes include FlexMock::MockContainer # Alias the original teardown behavior for later use. alias :flexmock_original_teardown :teardown # Teardown the test case, verifying any mocks that might have been # defined in this test case. def teardown flexmock_teardown flexmock_original_teardown end end end end end if defined?(MiniTest) module MiniTest class Unit class TestCase FlexMock::GenericTestCase.define_extensions_on(self) end end end else module Test module Unit class TestCase FlexMock::GenericTestCase.define_extensions_on(self) end end end end flexmock-2.0.4/lib/flexmock/undefined.rb000066400000000000000000000017411263476550700202130ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ class FlexMock # Undefined is a self preserving undefined object. The result of # any interaction with the undefined object will be the undefined # object itself. class Undefined def method_missing(sym, *args, &block) self end def to_s "-UNDEFINED-" end def inspect to_s end def clone self end def <=>(other) self end def coerce(other) [FlexMock.undefined, FlexMock.undefined] end end # Single instance of undefined @undefined = Undefined.new # Undefined is normally available as FlexMock.undefined def self.undefined @undefined end class << Undefined private :new end end flexmock-2.0.4/lib/flexmock/validators.rb000077500000000000000000000064731263476550700204340ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'flexmock/noop' require 'flexmock/spy_describers' class FlexMock #################################################################### # Base class for all the count validators. # class CountValidator include FlexMock::SpyDescribers def initialize(expectation, limit) @exp = expectation @limit = limit end # If the expectation has been called +n+ times, is it still # eligible to be called again? The default answer compares n to # the established limit. def eligible?(n) n < @limit end # Human readable description of the validator def describe case @limit when 0 ".never" when 1 ".once" when 2 ".twice" else ".times(#{@limit})" end end def describe_limit @limit.to_s end class ValidationFailed < RuntimeError end def validate_count(n, &block) unless yield raise ValidationFailed, construct_validation_count_error_message(n) end end private # Build the error message for an invalid count def construct_validation_count_error_message(n) "Method '#{@exp}' called incorrect number of times\n" + "#{describe_limit} matching #{calls(@limit)} expected\n" + "#{n} matching #{calls(n)} found\n" + describe_calls(@exp.mock) end # Pluralize "call" def calls(n) n == 1 ? "call" : "calls" end end #################################################################### # Validator for exact call counts. # class ExactCountValidator < CountValidator # Validate that the method expectation was called exactly +n+ # times. def validate(n) validate_count(n) { @limit == n } end end #################################################################### # Validator for call counts greater than or equal to a limit. # class AtLeastCountValidator < CountValidator # Validate the method expectation was called no more than +n+ # times. def validate(n) validate_count(n) { n >= @limit } end # Human readable description of the validator. def describe if @limit == 0 ".zero_or_more_times" else ".at_least#{super}" end end # If the expectation has been called +n+ times, is it still # eligible to be called again? Since this validator only # establishes a lower limit, not an upper limit, then the answer # is always true. def eligible?(n) true end def describe_limit "At least #{@limit}" end end #################################################################### # Validator for call counts less than or equal to a limit. # class AtMostCountValidator < CountValidator # Validate the method expectation was called at least +n+ times. def validate(n) validate_count(n) { n <= @limit } end # Human readable description of the validator def describe ".at_most#{super}" end def describe_limit "At most #{@limit}" end end end flexmock-2.0.4/lib/flexmock/version.rb000066400000000000000000000000511263476550700177300ustar00rootroot00000000000000class FlexMock VERSION = "2.0.4" end flexmock-2.0.4/rakelib/000077500000000000000000000000001263476550700147555ustar00rootroot00000000000000flexmock-2.0.4/rakelib/metrics.rake000066400000000000000000000016551263476550700172760ustar00rootroot00000000000000METRICS_FILES = FileList['lib/**/*.rb'] task :metrics => [:cane, :flog, :flay] task :flog, [:all] do |t, args| flags = args.all ? "--all" : "" flags = "-m #{flags}" Bundler.with_clean_env do puts "\nFLOG:" sh "flog #{flags} #{METRICS_FILES}" do |status, flag| if status.nil? puts "Install flog with: 'gem install flog'" end end end end task :flay do Bundler.with_clean_env do puts "\nFLAY:" sh "flay #{METRICS_FILES}" do |status, flag| if status.nil? puts "Install flay with: 'gem install flay'" end end end end task :cane, [:max_line] do |t, args| max_line = args.max_line || 90 Bundler.with_clean_env do puts "\nCANE:" sh "cane --style-measure #{max_line} --no-doc" do |status, flag| if status.nil? puts "DBG: [status, flag]=#{[status, flag].inspect}" puts "Install cane with: 'gem install cane'" end end end end flexmock-2.0.4/rakelib/preview.rake000066400000000000000000000001131263476550700172750ustar00rootroot00000000000000 task :preview do sh "ghpreview #{FileList['README.{md,markdown}']}" end flexmock-2.0.4/rakelib/tags.rake000066400000000000000000000006311263476550700165570ustar00rootroot00000000000000#!/usr/bin/env ruby # -*- ruby -*- module Tags RUBY_FILES = FileList['**/*.rb'].exclude("pkg") PROG = ENV['TAGS'] || 'ctags' end namespace "tags" do desc "Update the Tags file for emacs" task :emacs => Tags::RUBY_FILES do puts "Making Emacs TAGS file" sh "#{Tags::PROG} -e #{Tags::RUBY_FILES}", :verbose => false end end desc "Update the Tags file for emacs" task :tags => ["tags:emacs"] flexmock-2.0.4/test/000077500000000000000000000000001263476550700143235ustar00rootroot00000000000000flexmock-2.0.4/test/aliasing_test.rb000066400000000000000000000030551263476550700175010ustar00rootroot00000000000000#!/usr/bin/env ruby require 'test_helper' # This is an experimental test to see if mock and stub methods can # easily be added to a flexmock core. These test are disabled by # default, and should be reviewed before something more production # oriented is provided. if ENV['TEST_ALIASES'] class FlexMock module StubsAndExpects def expects(*args) result = should_receive(*args) result.at_least.once unless result.call_count_constrained? result end def stubs(*args) should_receive(*args) end end module MockContainer alias :mock :flexmock alias :stub :flexmock end include StubsAndExpects class PartialMockProxy include StubsAndExpects MOCK_METHODS << :stubs << :expects end end class AliasingTest < Minitest::Test include FlexMock::Minitest def test_mocking m = mock("a cute dog").expects(:pat).twice.and_return(:woof!).mock assert_equal :woof!, m.pat assert_equal :woof!, m.pat end def test_once_mocking mock("a cute dog").expects(:pat).and_return(:woof!).mock end def test_twice_mocking m = mock("a cute dog").expects(:pat).and_return(:woof!).twice.mock assert_raises(assertion_failed_error) { m.flexmock_verify } end def test_stubbing m = stub("a cute dog").expects(:pat).and_return(:woof!).mock assert_equal :woof!, m.pat end def test_partial obj = Object.new stub(obj).stubs(:wag).and_return(:tail) assert_equal :tail, obj.wag end end end flexmock-2.0.4/test/assert_spy_called_test.rb000066400000000000000000000053541263476550700214160ustar00rootroot00000000000000#!/usr/bin/env ruby require 'test_helper' require 'flexmock/test_unit_assert_spy_called' class AssertSpyCalledTest < Minitest::Test include FlexMock::Minitest class FooBar def foo end def bar end end def setup super @spy = flexmock(:on, FooBar) end def spy @spy end def test_assert_detects_basic_call spy.foo assert_spy_called spy, :foo end def test_assert_detects_basic_call_with_args spy.foo(1,2) assert_spy_called spy, :foo, 1, 2 end def test_assert_rejects_incorrect_args spy.foo(1,2) assert_fails(/^expected foo\(1, 3\) to be received by /i) do assert_spy_called spy, :foo, 1, 3 end end def test_assert_detects_multiple_calls spy.foo spy.foo spy.foo assert_spy_called spy, {:times => 3}, :foo end def test_assert_rejects_incorrect_type spy.foo spy.foo assert_fails(/^expected foo\(\) to be received by 3 times/i) do assert_spy_called spy, {:times => 3}, :foo end end def test_assert_detects_blocks spy.foo { } spy.bar assert_spy_called spy, :foo, Proc assert_spy_called spy, :bar end def test_assert_detects_any_args spy.foo spy.foo(1) spy.foo("HI") spy.foo("Hello", "World", 10, :options => true) assert_spy_called spy, {:times => 4}, :foo, :_ end def test_assert_rejects_bad_count_on_any_args spy.foo assert_fails(/^expected foo\(\*args\) to be received by twice/i) do assert_spy_called spy, {:times => 2}, :foo, :_ end end def test_assert_error_lists_calls_actually_made_without_handled_by spy.foo spy.bar(1) ex = assert_fails(/The following messages have been received/) do assert_spy_called spy, :baz end assert_match(/ foo\(\)/, ex.message) assert_match(/ bar\(1\)/, ex.message) refute_match(/ baz\(\)/, ex.message) refute_match(/handled by/, ex.message) end def test_assert_error_lists_calls_actually_made_with_handled_by spy.should_receive(:foo).once spy.foo spy.bar(1) ex = assert_fails(/The following messages have been received/) do assert_spy_called spy, :baz end assert_match(/ foo\(\) matched by should_receive\(:foo\)/, ex.message) assert_match(/ bar\(1\)/, ex.message) refute_match(/ baz\(\)/, ex.message) end def test_assert_errors_say_no_calls_made assert_fails(/No messages have been received/) do assert_spy_called spy, :baz end end private def assert_fails(message_pattern) ex = assert_raises(assertion_failed_error) do yield end assert_match(message_pattern, ex.message) ex end end flexmock-2.0.4/test/base_class_test.rb000066400000000000000000000043351263476550700200130ustar00rootroot00000000000000require 'test_helper' class BaseClassTest < Minitest::Test include FlexMock::Minitest class FooBar def foo end def method_missing(sym, *args, &block) return :poof if sym == :barq super end def respond_to?(method) method == :barq || super end end def mock @mock ||= flexmock(:on, FooBar) end def test_base_class_auto_mocks_class assert_equal FooBar, mock.class end def test_base_class_auto_mocks_kind_of assert mock.kind_of?(FooBar) end def test_base_class_auto_mocks_base_class_methods assert_equal FlexMock.undefined, mock.foo end def test_base_class_does_not_mock_non_base_class_methods assert_raises(NoMethodError) do mock.fuzz end end def test_can_stub_existing_methods mock.should_receive(:foo => :bar) assert_equal :bar, mock.foo end def test_can_not_stub_non_class_defined_methods ex = assert_raises(NoMethodError) do mock.should_receive(:baz => :bar) end assert_match(/can *not stub methods.*base.*class/i, ex.message) assert_match(/class:.+FooBar/i, ex.message) assert_match(/method:.+baz/i, ex.message) end def test_can_not_stub_non_class_methods_in_single_line ex = assert_raises(NoMethodError) do flexmock(:on, FooBar, :bark => :value) end assert_match(/can *not stub methods.*base.*class/i, ex.message) assert_match(/class:.+FooBar/i, ex.message) assert_match(/method:.+bark/i, ex.message) end def test_can_stub_subclasses_of_BasicObject_on_a_single_line klass = Class.new(BasicObject) do def stub_this; end end mock = flexmock(:on, klass, stub_this: 10) assert_equal 10, mock.stub_this end def test_can_stub_subclasses_of_BasicObject klass = Class.new(BasicObject) do def stub_this; end end mock = flexmock(:on, klass) mock.should_receive(:stub_this).and_return(10) assert_equal 10, mock.stub_this end def test_can_explicitly_stub_non_class_defined_methods mock.should_receive(:baz).explicitly.and_return(:bar) assert_equal :bar, mock.baz end def test_can_explicitly_stub_meta_programmed_methods mock.should_receive(:barq).explicitly.and_return(:bar) assert_equal :bar, mock.barq end end flexmock-2.0.4/test/based_partials_test.rb000066400000000000000000000021741263476550700206700ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class BasedPartialsTest < Minitest::Test include FlexMock::Minitest def setup super FlexMock.partials_are_based = true end def teardown FlexMock.partials_are_based = false super end class Dog def bark :woof end end def test_based_partials_allow_stubbing_defined_methods dog = Dog.new flexmock(dog).should_receive(:bark => :mock_value) assert_equal :mock_value, dog.bark end def test_based_partials_disallow_stubbing_undefined_methods dog = Dog.new assert_raises(NoMethodError, /cannot stub.*wag.*explicitly/) do flexmock(dog).should_receive(:wag => :mock_value) end end def test_based_partials_allow_explicitly_stubbing_undefined_methods dog = Dog.new flexmock(dog).should_receive(:wag).explicitly.and_return(:mock_value) end end flexmock-2.0.4/test/container_methods_test.rb000077500000000000000000000064511263476550700214250ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require "test_helper" # These tests exercise the interface used to define mocks class TestFlexmockContainerMethods < Minitest::Test include FlexMock::Minitest def test_simple_mock_creation mock = flexmock mock.should_receive(:hi).once.and_return(:lo) assert_equal :lo, mock.hi end def test_mock_with_name mock = flexmock("Danny") mock.should_receive(:xxx).with(1) ex = assert_raises(check_failed_error) { mock.xxx } assert_match(/Danny/, ex.message) end def test_mock_with_symbol_name mock = flexmock(:Danny) mock.should_receive(:xxx).with(1) ex = assert_raises(check_failed_error) { mock.xxx } assert_match(/Danny/, ex.message) end def test_mock_with_hash mock = flexmock(:hi => :lo, :good => :bye) assert_equal :lo, mock.hi assert_equal :bye, mock.good end def test_mock_with_name_and_hash mock = flexmock("Danny", :hi => :lo, :good => :bye) mock.should_receive(:xxx).with(1) assert_equal :lo, mock.hi assert_equal :bye, mock.good ex = assert_raises(check_failed_error) { mock.xxx } assert_match(/Danny/, ex.message) end def test_mock_with_name_hash_and_block mock = flexmock("Danny", :hi => :lo, :good => :bye) do |m| m.should_receive(:one).and_return(1) end assert_equal 1, mock.one assert_equal :lo, mock.hi end def test_mock_does_not_do_any_validation_once_closed mock = flexmock mock.should_receive(:hi).once.with(20) mock.hi(20) flexmock_teardown mock.does_not_exist mock.hi end def test_basic_stub fido = Object.new mock = flexmock(fido) mock.should_receive(:wag).and_return(:happy) assert_equal :happy, fido.wag end def test_basic_stub_with_name fido = Object.new mock = flexmock(fido, "Danny") mock.should_receive(:xxx).with(1).and_return(:happy) ex = assert_raises(check_failed_error) { fido.xxx } assert_match(/Danny/, ex.message) end def test_stub_with_quick_definitions fido = Object.new flexmock(fido, :wag => :happy) assert_equal :happy, fido.wag end def test_stub_with_name_quick_definitions fido = Object.new mock = flexmock(fido, "Danny", :wag => :happy) mock.should_receive(:xxx).with(1).and_return(:happy) ex = assert_raises(check_failed_error) { fido.xxx } assert_match(/Danny/, ex.message) assert_equal :happy, fido.wag end def test_stubs_are_auto_verified fido = Object.new mock = flexmock(fido) mock.should_receive(:hi).once assert_raises(assertion_failed_error) { flexmock_verify } end def test_stubbing_a_string s = "hello" flexmock(:base, s, :length => 2) assert_equal 2, s.length end def test_multiple_stubs_work_with_same_partial_mock_proxy obj = Object.new mock1 = flexmock(obj) mock2 = flexmock(obj) assert_equal mock1, mock2 end def test_multiple_stubs_layer_behavior obj = Object.new flexmock(obj, :hi => :lo) flexmock(obj, :high => :low) assert_equal :lo, obj.hi assert_equal :low, obj.high end end flexmock-2.0.4/test/default_framework_adapter_test.rb000077500000000000000000000013651263476550700231200ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require "test_helper" class TestFlexmockDefaultFrameworkAdapter < Minitest::Test def setup @adapter = FlexMock::DefaultFrameworkAdapter.new end def test_assert_block_raises_exception assert_raises(FlexMock::DefaultFrameworkAdapter::AssertionFailedError) { @adapter.check("failure message") { false } } end def test_make_assertion_doesnt_raise_exception_when_making_assertion @adapter.check("failure message") { true } end end flexmock-2.0.4/test/demeter_mocking_test.rb000066400000000000000000000132641263476550700210510ustar00rootroot00000000000000#!/usr/bin/env ruby require 'test_helper' class TestDemeterMocking < Minitest::Test include FlexMock::Minitest def test_demeter_mocking_basics m = flexmock("A") m.should_receive("children.first").and_return(:first) assert_kind_of FlexMock, m assert_kind_of FlexMock, m.children assert_equal :first, m.children.first end def test_demeter_mocking_with_operators m = flexmock("A") m.should_receive("children.+@.last").and_return(:value) assert_kind_of FlexMock, m assert_kind_of FlexMock, m.children assert_kind_of FlexMock, + m.children assert_equal :value, (+ m.children).last end def test_demeter_mocking_with_multiple_operators m = flexmock("A") m.should_receive("+@.-@.~").and_return(:value) assert_equal :value, ~-+m end def test_multiple_demeter_mocks_on_same_branch_is_ok m = flexmock("A") m.should_receive("child.x.y.z.first").and_return(:first) m.should_receive("child.x.y.z.last").and_return(:last) assert_equal :first, m.child.x.y.z.first assert_equal :last, m.child.x.y.z.last end def test_multi_level_deep_demeter_violation_with_mock a = flexmock("a") a.should_receive("b.c.d.e.f.g.h.i.j.k").and_return(:xyzzy) assert_equal :xyzzy, a.b.c.d.e.f.g.h.i.j.k end def test_partial_with_demeter a = flexmock(Object.new, "a partial") a.should_receive("b.c").and_return(:xyzzy) assert_equal :xyzzy, a.b.c end def test_multi_level_deep_demeter_violation_with_partial a = flexmock(Object.new, "a") a.should_receive("b.c.d.e.f.g.h.i.j.k").and_return(:xyzzy) assert_equal :xyzzy, a.b.c.d.e.f.g.h.i.j.k end def test_final_method_can_have_multiple_expecations a = flexmock("a") a.should_receive("b.c.d.last").with(1).and_return(:one).once a.should_receive("b.c.d.last").with(2).and_return(:two).once assert_equal :one, a.b.c.d.last(1) assert_equal :two, a.b.c.d.last(2) end def test_conflicting_mock_declarations_raises_an_error m = flexmock("A") ex = assert_raises(FlexMock::UsageError) do m.should_receive("child").and_return(:xyzzy) m.should_receive("child.other").and_return(:other) m.child.other end assert_match(/conflicting/i, ex.message) assert_match(/mock\s+declaration/i, ex.message) assert_match(/child/i, ex.message) end def test_compatible_mock_declarations_are_ok_full_mock_version m = flexmock("A") b = flexmock("B") c = flexmock("C") m.should_receive(:b => b) b.should_receive(:c => c) c.should_receive(:foo => :bar) m.should_receive("b.c.baz").and_return(:barg) m.should_receive("b.zhar").and_return(:zzz) assert_equal :bar, m.b.c.foo assert_equal :barg, m.b.c.baz assert_equal :zzz, m.b.zhar end def test_compatible_mock_declarations_are_ok_partial_mock_version m = flexmock("A") b = flexmock(Object.new, "B") c = flexmock("C") m.should_receive(:b => b) b.should_receive(:c => c) c.should_receive(:foo => :bar) m.should_receive("b.c.baz").and_return(:barg) m.should_receive("b.zhar").and_return(:zzz) assert_equal :bar, m.b.c.foo assert_equal :barg, m.b.c.baz assert_equal :zzz, m.b.zhar end def test_paths m = flexmock("A") b = flexmock("B") m.should_receive("a.b" => b) m.should_receive("a.b.c.x" => 1) m.should_receive("a.b.c.y" => 2) end def test_conflicting_mock_declarations_in_reverse_order_does_not_raise_error # Not all conflicting definitions can be detected. m = flexmock("A") assert_failure(assertion_failed_error) do m.should_receive("child.other").and_return(:other) m.should_receive("child").and_return(:xyzzy) assert_equal :xyzzy, m.child.other end end def test_preestablishing_existing_mock_is_ok engine = flexmock("engine") car = flexmock("A") car.should_receive(:engine).and_return(engine) car.should_receive("engine.cylinder").and_return(:cyl) assert_equal :cyl, car.engine.cylinder end def test_quick_defs_can_use_demeter_mocking a = flexmock("a") a.should_receive("b.c.d.x").and_return(:x) a.should_receive("b.c.d.y").and_return(:y) a.should_receive("b.c.d.z").and_return(:z) assert_equal :x, a.b.c.d.x assert_equal :y, a.b.c.d.y assert_equal :z, a.b.c.d.z end def test_quick_defs_can_use_demeter_mocking_two a = flexmock("a", "b.c.d.xx" => :x, "b.c.d.yy" => :y, "b.c.d.zz" => :z) assert_equal :x, a.b.c.d.xx assert_equal :y, a.b.c.d.yy assert_equal :z, a.b.c.d.zz end def test_errors_on_ill_formed_method_names m = flexmock("a") [ 'a(2)', '0a', 'a-b', 'a b', ' ', 'a ', ' b', 'a!b', "a?b", 'a=b' ].each do |method| assert_raises FlexMock::UsageError do m.should_receive(method) end end end def test_no_errors_on_well_formed_method_names m = flexmock("a") [ 'a', 'a?', 'a!', 'a=', 'z0', 'save!' ].each do |method| m.should_receive(method) end end def test_readme_example_1 cog = flexmock("cog") cog.should_receive(:turn).once.and_return(:ok).mock joint = flexmock("gear", :cog => cog) axle = flexmock("axle", :universal_joint => joint) chassis = flexmock("chassis", :axle => axle) car = flexmock("car", :chassis => chassis) assert_equal :ok, car.chassis.axle.universal_joint.cog.turn end def test_readme_example_2 car = flexmock("car") car.should_receive("chassis.axle.universal_joint.cog.turn" => :ok).once assert_equal :ok, car.chassis.axle.universal_joint.cog.turn end def test_readme_example_3 car = flexmock("car") car.should_receive("chassis.axle.universal_joint.cog.turn").once. and_return(:ok) assert_equal :ok, car.chassis.axle.universal_joint.cog.turn end end flexmock-2.0.4/test/deprecated_methods_test.rb000066400000000000000000000122611263476550700215340ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' require 'flexmock/deprecated_methods' class TestFlexMock < Minitest::Test include FlexMock::Minitest include FlexMock::RedirectError def s(&block) redirect_error(&block) end def setup @mock = flexmock('mock') end def test_handle args = nil s { @mock.mock_handle(:hi) { |a, b| args = [a,b] } } @mock.hi(1,2) assert_equal [1,2], args end def test_handle_no_block s { @mock.mock_handle(:blip) } @mock.blip assert true, "just checking for failures" end def test_called_with_block called = false s { @mock.mock_handle(:blip) { |block| block.call } } @mock.blip { called = true } assert called, "Block to blip should be called" end def test_return_value s { @mock.mock_handle(:blip) { 10 } } assert_equal 10, @mock.blip end def test_handle_missing_method expected_error = (RUBY_VERSION >= "1.8.0") ? NoMethodError : NameError ex = assert_raises(expected_error) { @mock.not_defined } assert_match(/not_defined/, ex.message) end def test_ignore_missing_method @mock.mock_ignore_missing @mock.blip assert true, "just checking for failures" end def test_good_counts s { @mock.mock_handle(:blip, 3) } @mock.blip @mock.blip @mock.blip @mock.flexmock_verify end def test_bad_counts s { @mock.mock_handle(:blip, 3) } @mock.blip @mock.blip begin @mock.flexmock_verify rescue assertion_failed_error => err end refute_nil err end def test_undetermined_counts FlexMock.use('fs') { |m| s { m.mock_handle(:blip) } m.blip m.blip m.blip } end def test_zero_counts assert_raises(check_failed_error) do FlexMock.use { |m| s { m.mock_handle(:blip, 0) } m.blip } end end def test_file_io_with_use FlexMock.use do |m| filedata = ["line 1", "line 2"] s { m.mock_handle(:gets, 3) { filedata.shift } } assert_equal 2, count_lines(m) end end def count_lines(stream) result = 0 while stream.gets result += 1 end result end def test_use assert_raises(assertion_failed_error) { FlexMock.use do |m| s { m.mock_handle(:blip, 2) } m.blip end } end def test_failures_during_use ex = assert_raises(NameError) { FlexMock.use do |m| s { m.mock_handle(:blip, 2) } xyz end } assert_match(/undefined local variable or method/, ex.message) end def test_sequential_values values = [1,4,9,16] s { @mock.mock_handle(:get) { values.shift } } assert_equal 1, @mock.get assert_equal 4, @mock.get assert_equal 9, @mock.get assert_equal 16, @mock.get end def test_respond_to_returns_false_for_non_handled_methods assert(!@mock.respond_to?(:blah), "should not respond to blah") end def test_respond_to_returns_true_for_explicit_methods s { @mock.mock_handle(:xyz) } assert(@mock.respond_to?(:xyz), "should respond to test") end def test_respond_to_returns_true_for_missing_methods_when_ignoring_missing @mock.mock_ignore_missing assert(@mock.respond_to?(:yada), "should respond to yada now") end def test_respond_to_returns_true_for_missing_methods_when_ignoring_missing_using_should @mock.should_ignore_missing assert(@mock.respond_to?(:yada), "should respond to yada now") end def test_method_proc_raises_error_on_unknown assert_raises(NameError) { @mock.method(:xyzzy) } end def test_method_returns_callable_proc got_it = false s { @mock.mock_handle(:xyzzy) { got_it = true } } method_proc = @mock.method(:xyzzy) refute_nil method_proc method_proc.call([]) assert(got_it, "method proc should run") end def test_method_returns_do_nothing_proc_for_missing_methods @mock.mock_ignore_missing method_proc = @mock.method(:plugh) refute_nil method_proc assert_equal FlexMock.undefined, method_proc.call end end class TestDeprecatedOrderingMethods < Minitest::Test include FlexMock::Minitest include FlexMock::RedirectError def test_deprecated_ordering_methods flexmock(:x).should_receive(:msg).globally.ordered(:testgroup) assert_equal({ :testgroup => 1 }, flexmock_groups) message = redirect_error do assert_equal({ :testgroup => 1 }, mock_groups) end assert_match(/deprecated/i, message) assert_match(/\bmock_groups/, message) assert_match(/\bflexmock_groups/, message) end end class TestAnyInstance < Minitest::Test include FlexMock::Minitest include FlexMock::RedirectError class Dog def bark :woof end end def test_any_instance_still_works_for_backwards_compatibility message = redirect_error do flexstub(Dog).any_instance do |obj| obj.should_receive(:bark).and_return(:whimper) assert_match(/deprecated/, message) end end m = Dog.new assert_equal :whimper, m.bark end end flexmock-2.0.4/test/examples_from_readme_test.rb000066400000000000000000000077731263476550700221030ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class TemperatureSampler def initialize(sensor) @sensor = sensor end def average_temp total = (0...3).collect { @sensor.read_temperature }.inject { |i, s| i + s } total / 3.0 end end class TestTemperatureSampler < Minitest::Test include FlexMock::Minitest def test_tempurature_sampler readings = [10, 12, 14] mock_sensor = flexmock("sensor") mock_sensor.should_receive(:read_temperature).and_return { readings.shift } sampler = TemperatureSampler.new(mock_sensor) assert_equal 12, sampler.average_temp end end class TestExamplesFromReadme < Minitest::Test include FlexMock::Minitest def test_simple_return_values m = flexmock(:pi => 3.1416, :e => 2.71) assert_equal 3.1416, m.pi assert_equal 2.71, m.e end def test_returning_an_undefined_value m = flexmock("mock") m.should_receive(:foo).and_return_undefined m.foo.bar.baz end def test_db db = flexmock('db') db.should_receive(:query).and_return([1,2,3]) db.should_receive(:update).with(5).and_return(nil).once # test code here assert_equal [1, 2, 3], db.query db.update(5) end def test_query_and_update db = flexmock('db') db.should_receive(:query).and_return([1,2,3]).ordered db.should_receive(:update).and_return(nil).ordered # test code here assert_equal [1,2,3], db.query assert_nil db.update end def test_ordered_queries db = flexmock('db') db.should_receive(:startup).once.ordered db.should_receive(:query).with("GOOG").and_return(12.3). once.ordered(:queries) db.should_receive(:query).with("APPL").and_return(10.0). once.ordered(:queries) db.should_receive(:query).with(/^....$/).and_return(3.3). at_least.once.ordered(:queries) db.should_receive(:finish).once.ordered # test code here db.startup assert_equal 3.3, db.query("WXYZ") assert_equal 10.0, db.query("APPL") assert_equal 12.3, db.query("GOOG") db.finish end def test_ordered_queries_in_record_mode db = flexmock('db') db.should_expect do |rec| rec.startup.once.ordered rec.query("GOOG") { 12.3 }.once.ordered(:queries) rec.query("APPL") { 10.0 }.once.ordered(:queries) rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries) rec.finish.once.ordered end # test code here using +db+. db.startup assert_equal 10.0, db.query("APPL") assert_equal 12.3, db.query("GOOG") assert_equal 3.3, db.query("WXYZ") db.finish end def test_build_xml builder = flexmock('builder') builder.should_expect do |rec| rec.should_be_strict known_good_way_to_build_xml(rec) # record the messages end new_way_to_build_xml(builder) # compare to new way end def known_good_way_to_build_xml(rec) rec.one rec.two end def new_way_to_build_xml(rec) [:one, :two].each do |sym| rec.send(sym) end end def test_multiple_gets file = flexmock('file') file.should_receive(:gets).with_no_args. and_return("line 1\n", "line 2\n") # test code here assert_equal "line 1\n", file.gets assert_equal "line 2\n", file.gets end def test_an_important_message m = flexmock('m') m.should_receive(:an_important_message).and_return(1).once m.should_ignore_missing # test code here m.an_important_message m.unknown_message.bar.baz end class QuoteService end class Portfolio def value QuoteService.new.quote end end def test_portfolio_value flexmock(QuoteService).new_instances do |m| m.should_receive(:quote).and_return(100) end port = Portfolio.new value = port.value # Portfolio calls QuoteService.quote assert_equal 100, value end end flexmock-2.0.4/test/expectation_description_test.rb000066400000000000000000000037341263476550700226440ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class ExpectationDescriptionTest < Minitest::Test include FlexMock::Minitest def setup @mock = flexmock("mock") @exp = FlexMock::Expectation.new(@mock, :foo, "file.rb:3") end def test_basic_description assert_equal "should_receive(:foo)", @exp.description end def test_with_no_args @exp.with() assert_equal "should_receive(:foo).with()", @exp.description end def test_with_simple_args @exp.with(1, "HI") assert_equal "should_receive(:foo).with(1, \"HI\")", @exp.description end def test_with_never @exp.never assert_equal "should_receive(:foo).never", @exp.description end def test_with_once @exp.once assert_equal "should_receive(:foo).once", @exp.description end def test_with_twice @exp.twice assert_equal "should_receive(:foo).twice", @exp.description end def test_with_3 @exp.times(3) assert_equal "should_receive(:foo).times(3)", @exp.description end def test_with_at_least_once @exp.at_least.once assert_equal "should_receive(:foo).at_least.once", @exp.description end def test_with_at_least_10 @exp.at_least.times(10) assert_equal "should_receive(:foo).at_least.times(10)", @exp.description end def test_with_at_most_once @exp.at_most.once assert_equal "should_receive(:foo).at_most.once", @exp.description end def test_with_zero_or_more_times @exp.at_most.zero_or_more_times assert_equal "should_receive(:foo).zero_or_more_times", @exp.description end def test_with_at_least_1_at_most_10 @exp.at_least.once.at_most.times(10) assert_equal "should_receive(:foo).at_least.once.at_most.times(10)", @exp.description end end flexmock-2.0.4/test/extended_should_receive_test.rb000077500000000000000000000033341263476550700225750ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require "test_helper" module ExtendedShouldReceiveTests def test_accepts_expectation_hash @mock.should_receive( :foo => :bar, :baz => :froz ) assert_equal :bar, @obj.foo assert_equal :froz, @obj.baz end def test_accepts_list_of_methods @mock.should_receive(:foo, :bar, "baz") assert_nil @obj.foo assert_nil @obj.bar assert_nil @obj.baz end def test_contraints_apply_to_all_expectations @mock.should_receive(:foo, :bar => :baz).with(1) ex = assert_raises(check_failed_error) { @obj.foo(2) } ex = assert_raises(check_failed_error) { @obj.bar(2) } assert_equal :baz, @obj.bar(1) end def test_count_contraints_apply_to_all_expectations @mock.should_receive(:foo, :bar => :baz).once @obj.foo assert_raises(assertion_failed_error) { @mock.flexmock_verify } end def test_multiple_should_receives_are_allowed @mock.should_receive(:hi).and_return(:bye). should_receive(:hello => :goodbye) assert_equal :bye, @obj.hi assert_equal :goodbye, @obj.hello end end class TestExtendedShouldReceiveOnFullMocks < Minitest::Test include FlexMock::Minitest include ExtendedShouldReceiveTests def setup @mock = flexmock("mock") @obj = @mock end end class TestExtendedShouldReceiveOnPartialMockProxies < Minitest::Test include FlexMock::Minitest include ExtendedShouldReceiveTests def setup @obj = Object.new @mock = flexmock(@obj, "mock") end end flexmock-2.0.4/test/flexmodel_test.rb000066400000000000000000000025251263476550700176720ustar00rootroot00000000000000#!/usr/bin/env ruby require 'test_helper' class DummyModel end class ChildModel < DummyModel end ###################################################################### class TestFlexModel < Minitest::Test include FlexMock::Minitest def test_initial_conditions model = flexmock(:model, DummyModel) assert_match(/^DummyModel_\d+/, model.flexmock_name) assert_equal model.id.to_s, model.to_params assert ! model.new_record? assert model.is_a?(DummyModel) # TODO: Make these work!!! assert_equal DummyModel, model.class assert model.instance_of?(DummyModel) assert model.kind_of?(DummyModel) end def test_classifying_mock_models model = flexmock(:model, ChildModel) assert model.kind_of?(ChildModel) assert model.instance_of?(ChildModel) assert model.kind_of?(DummyModel) assert ! model.instance_of?(DummyModel) end def test_mock_models_have_different_ids m1 = flexmock(:model, DummyModel) m2 = flexmock(:model, DummyModel) assert m2.id != m1.id end def test_mock_models_can_have_quick_defs model = flexmock(:model, DummyModel, :xyzzy => :ok) assert_equal :ok, model.xyzzy end def test_mock_models_can_have_blocks model = flexmock(:model, DummyModel) do |m| m.should_receive(:xyzzy => :okdokay) end assert_equal :okdokay, model.xyzzy end end flexmock-2.0.4/test/minitest_integration/000077500000000000000000000000001263476550700205625ustar00rootroot00000000000000flexmock-2.0.4/test/minitest_integration/auto_test.rb000077500000000000000000000036071263476550700231270ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'minitest/autorun' require "test_helper" require "flexmock/base" require "flexmock/minitest" if defined?(Minitest::Test) class TestFlexmockMinitest < Minitest::Test include FlexMock::Minitest def before_teardown # flexmock should be teared down right now, and the teardown result should # be registered in the test failures (specific to minitest 5.0+) super if @should_fail assert 1, failures.size else assert 0, failures.size end # Clear failures ... otherwise the test will fail failures.clear assert @closed end def flexmock_close @closed = true super end end else class TestFlexmockMinitest < MiniTest::Unit::TestCase include FlexMock::Minitest def before_teardown # flexmock should be teared down right now, but nothing should be raised # yet. The error will be raised in after_teardown super assert @closed end def after_teardown begin super failed = false rescue Exception => e failed = true end assert_equal @should_fail, failed, "Expected failed to be #{@should_fail}" end end end class TestFlexmockMinitest def flexmock_close @closed = true super end # This test should pass. def test_can_create_mocks m = flexmock("mock") m.should_receive(:hi).once m.hi @should_fail = false end # This test should fail during teardown. def test_should_fail__mocks_are_auto_verified m = flexmock("mock") m.should_receive(:hi).once @should_fail = true end end flexmock-2.0.4/test/minitest_integration/minitest_teardown_test.rb000066400000000000000000000003551263476550700257100ustar00rootroot00000000000000require "minitest/autorun" require 'flexmock/minitest' testclass = if defined?(Minitest::Test) then Minitest::Test else MiniTest::Unit::TestCase end class SimpleTest < testclass def test_flexmock flexmock() end end flexmock-2.0.4/test/mock_builder_test.rb000066400000000000000000000034151263476550700203510ustar00rootroot00000000000000require 'test_helper' class MockBuilderTest < Minitest::Test include FlexMock::Minitest def assert_method_name(name) assert_match(FlexMock::ExpectationBuilder::METHOD_NAME_RE, name) end def refute_method_name(name) refute_match(FlexMock::ExpectationBuilder::METHOD_NAME_RE, name) end def test_valid_method_names assert_method_name "foo" assert_method_name "FooBar" assert_method_name "_foo" assert_method_name "__foo" assert_method_name "___foo" assert_method_name "_" assert_method_name "foo_bar" assert_method_name "foo__bar" assert_method_name "foo_bar_" assert_method_name "foo12" assert_method_name "foo_bar_12" assert_method_name "foo?" assert_method_name "foo!" assert_method_name "foo=" assert_method_name "+" assert_method_name "-" assert_method_name "*" assert_method_name "/" assert_method_name "&" assert_method_name "|" assert_method_name "^" assert_method_name "~" assert_method_name "=~" assert_method_name "!~" assert_method_name "`" assert_method_name "!" assert_method_name "**" assert_method_name "+@" assert_method_name "-@" assert_method_name "==" assert_method_name "!=" assert_method_name "===" assert_method_name "<=" assert_method_name ">=" assert_method_name "<" assert_method_name ">" assert_method_name "<=>" assert_method_name "[]" assert_method_name "[]=" end def test_invalid_method_names refute_method_name "" refute_method_name "1" refute_method_name "1foo" refute_method_name "foo!!" refute_method_name "foo!?" refute_method_name "foo?=" refute_method_name "foo@" refute_method_name "++" refute_method_name "!!" refute_method_name "~=" end end flexmock-2.0.4/test/naming_test.rb000066400000000000000000000037401263476550700171640ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class TestNaming < Minitest::Test include FlexMock::Minitest def test_name m = flexmock("m") assert_equal "m", m.flexmock_name end def test_name_in_no_handler_found_error m = flexmock("mmm") ex = assert_raises(check_failed_error) { m.should_receive(:xx).with(1) m.xx(2) } assert_match(/'mmm'/, ex.message) end def test_name_in_received_count_error m = flexmock("mmm") ex = assert_raises(assertion_failed_error) { m.should_receive(:xx).once m.flexmock_verify } assert_match(/'mmm'/, ex.message) end def test_naming_with_use FlexMock.use("blah") do |m| assert_equal "blah", m.flexmock_name end end def test_naming_with_multiple_mocks_in_use FlexMock.use("blah", "yuk") do |a, b| assert_equal "blah", a.flexmock_name assert_equal "yuk", b.flexmock_name end end def test_inspect_returns_reasonable_name FlexMock.use("XYZZY") do |m| assert_equal "XYZZY", m.flexmock_name assert_equal "", m.inspect end end def test_mock_can_override_inspect FlexMock.use("XYZZY") do |m| m.should_receive(:inspect).with_no_args.and_return("MOCK-INSPECT") assert_equal "MOCK-INSPECT", m.inspect end end class Dummy def inspect "DUMMY-INSPECT" end end def test_partial_mocks_use_original_inspect dummy = Dummy.new flexmock(dummy).should_receive(:msg) assert_equal "DUMMY-INSPECT", dummy.inspect end def test_partial_mocks_can_override_inspect dummy = Dummy.new flexmock(dummy).should_receive(:inspect).and_return("MOCK-INSPECT") assert_equal "MOCK-INSPECT", dummy.inspect end end flexmock-2.0.4/test/new_instances_test.rb000077500000000000000000000124301263476550700205520ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class TestNewInstances < Minitest::Test include FlexMock::Minitest include FlexMock::RedirectError class Dog def bark :woof end def wag :tail end def self.make new end end class Cat attr_reader :name def initialize(name, &block) @name = name block.call(self) if block_given? end end class Connection def initialize(*args) yield(self) if block_given? end def send(args) post(args) end def post(args) :unstubbed end end def test_new_instances_allows_stubbing_of_existing_methods flexstub(Dog).new_instances do |obj| obj.should_receive(:bark).and_return(:whimper) end m = Dog.new assert_equal :whimper, m.bark end def test_new_instances_stubs_still_have_existing_methods flexstub(Dog).new_instances do |obj| obj.should_receive(:bark).and_return(:whimper) end m = Dog.new assert_equal :tail, m.wag end def test_new_instances_will_pass_args_to_new flexstub(Cat).new_instances do |obj| obj.should_receive(:meow).and_return(:scratch) end x = :not_called m = Cat.new("Fido") { x = :called } assert_equal :scratch, m.meow assert_equal "Fido", m.name assert_equal :called, x end # Some versions of the software had problems invoking the block after a # second stubbing. def test_new_gets_block_after_restubbing flexstub(Cat).new_instances { } x = :not_called m = Cat.new("Fido") { x = :called } assert_equal :called, x flexmock_teardown flexstub(Cat).new_instances { } x = :not_called m = Cat.new("Fido") { x = :called } assert_equal :called, x end def test_new_instances_stub_verification_happens_on_teardown flexstub(Dog).new_instances do |obj| obj.should_receive(:bark).once.and_return(nil) end Dog.new ex = assert_raises(assertion_failed_error) { flexmock_teardown } assert_match(/method 'bark\(.*\)' called incorrect number of times/i, ex.message) end def test_new_instances_reports_error_on_non_classes ex = assert_raises(ArgumentError) { flexstub(Dog.new).new_instances do |obj| obj.should_receive(:hi) end } assert_match(/Class/, ex.message) assert_match(/new_instances/, ex.message) end def test_does_not_by_default_stub_objects_created_with_allocate flexstub(Dog).new_instances do |obj| obj.should_receive(:bark).and_return(:whimper) end m = Dog.allocate assert_equal :woof, m.bark end def test_can_explicitly_stub_objects_created_with_allocate flexstub(Dog).new_instances(:allocate) do |obj| obj.should_receive(:bark).and_return(:whimper) end m = Dog.allocate assert_equal :whimper, m.bark end def test_can_stub_objects_created_with_arbitrary_class_methods flexstub(Dog).new_instances(:make) do |obj| obj.should_receive(:bark).and_return(:whimper) end assert_equal :whimper, Dog.make.bark end def test_stubbing_arbitrary_class_methods_leaves_new_alone flexstub(Dog).new_instances(:make) do |obj| obj.should_receive(:bark).and_return(:whimper) end assert_equal :woof, Dog.new.bark end def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_new counter = 0 flexstub(Dog).new_instances do |obj| counter += 1 end Dog.new assert_equal 1, counter end # Current behavior does not install stubs into the block passed to new. # This is rather difficult to achieve, although it would be nice. For the # moment, we assure that they are not stubbed, but I am willing to change # this in the future. def test_blocks_on_new_do_not_have_stubs_installed flexstub(Connection).new_instances do |new_con| new_con.should_receive(:post).and_return { :stubbed } end block_run = false Connection.new do |c| assert_equal :unstubbed, c.send("hi") block_run = true end assert block_run end def test_new_instances_accept_chained_expectations flexmock(Dog).new_instances. should_receive(:growl).and_return(:grr). should_receive(:roll_over).and_return(:flip) assert_equal :grr, Dog.new.growl assert_equal :flip, Dog.new.roll_over end def test_fancy_use_of_chained_should_received flexmock(Dog).new_instances.should_receive(:woof => :grrr) assert_equal :grrr, Dog.new.woof end def test_writable_accessors flexmock(Dog).new_instances.should_receive(:name=).with("fido") dog = Dog.new dog.name = 'fido' end def test_ordering_can_be_specified dog = Dog.new flexmock(dog).should_receive(:bark).once.ordered flexmock(dog).should_receive(:bite).once.ordered dog.bark dog.bite end def test_ordering_can_be_specified_in_groups dog = Dog.new flexmock(dog).should_receive(:wag).once.ordered(:safe) flexmock(dog).should_receive(:bark).once.ordered(:danger) flexmock(dog).should_receive(:bite).once.ordered(:danger) dog.wag dog.bite dog.bark end end flexmock-2.0.4/test/object_extensions_test.rb000066400000000000000000000010171263476550700214330ustar00rootroot00000000000000#!/usr/bin/env ruby require 'test_helper' require 'flexmock/object_extensions' class ObjectExtensionsTest < Minitest::Test def setup @obj = Object.new def @obj.smethod :ok end end def test_undefined_methods_are_not_singletons assert ! @obj.flexmock_singleton_defined?(:xyzzy) end def test_normal_methods_are_not_singletons assert ! @obj.flexmock_singleton_defined?(:to_s) end def test_singleton_methods_are_singletons assert @obj.flexmock_singleton_defined?(:smethod) end end flexmock-2.0.4/test/partial_mock_test.rb000066400000000000000000000362521263476550700203640ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class TestStubbing < Minitest::Test include FlexMock::Minitest class Dog def bark :woof end def Dog.create :new_dog end end class DogPlus < Dog def should_receive :dog_should end def new_instances :dog_new end def by_default :dog_by_default end end def test_attempting_to_partially_mock_existing_mock_is_noop m = flexmock("A") flexmock(m) assert ! m.instance_variables.include?(:@flexmock_proxy.flexmock_as_name) end def test_forcibly_removing_proxy_causes_failure obj = Object.new flexmock(obj) obj.instance_eval { @flexmock_proxy = nil } ex = assert_raises(RuntimeError) do obj.should_receive(:hi).and_return(:stub_hi) end assert(ex.message =~ /missing.*proxy/i) end def test_stub_command_add_behavior_to_arbitrary_objects_via_flexmock obj = Object.new flexmock(obj).should_receive(:hi).and_return(:stub_hi) assert_equal :stub_hi, obj.hi end def test_stub_command_add_behavior_to_arbitrary_objects_post_flexmock obj = Object.new flexmock(obj) obj.should_receive(:hi).and_return(:stub_hi) assert_equal :stub_hi, obj.hi end def test_stub_command_can_configure_via_block obj = Object.new flexmock(obj) do |m| m.should_receive(:hi).once.and_return(:stub_hi) end assert_equal :stub_hi, obj.hi end def test_stubbed_methods_can_take_blocks obj = Object.new flexmock(obj).should_receive(:with_block).once.with(Proc). and_return { |block| block.call } assert_equal :block, obj.with_block { :block } end def test_multiple_stubs_on_the_same_object_reuse_the_same_partial_mock obj = Object.new a = flexmock(obj) b = flexmock(obj) assert_equal a.object_id, b.object_id end def test_stubbed_methods_can_invoke_original_behavior_directly dog = Dog.new flexmock(dog).should_receive(:bark).pass_thru.once assert_equal :woof, dog.bark end def test_stubbed_methods_can_invoke_original_behavior_with_modification dog = Dog.new flexmock(dog).should_receive(:bark).pass_thru { |result| result.to_s.upcase }.once assert_equal "WOOF", dog.bark end def test_stubbed_methods_returning_partial_mocks flexmock(Dog).should_receive(:new).pass_thru { |dog| flexmock(dog, :beg => "Please") }.once dog = Dog.new assert_equal "Please", dog.beg assert_equal :woof, dog.bark end def test_multiple_methods_can_be_stubbed dog = Dog.new flexmock(dog).should_receive(:bark).and_return(:grrrr) flexmock(dog).should_receive(:wag).and_return(:happy) assert_equal :grrrr, dog.bark assert_equal :happy, dog.wag end def test_original_behavior_can_be_restored dog = Dog.new partial_mock = flexmock(dog) partial_mock.should_receive(:bark).once.and_return(:growl) assert_equal :growl, dog.bark partial_mock.flexmock_teardown assert_equal :woof, dog.bark assert_equal nil, dog.instance_variable_get("@flexmock_proxy").proxy end def test_original_missing_behavior_can_be_restored obj = Object.new partial_mock = flexmock(obj) partial_mock.should_receive(:hi).once.and_return(:ok) assert_equal :ok, obj.hi partial_mock.flexmock_teardown assert_raises(NoMethodError) { obj.hi } end def test_multiple_stubs_on_single_method_can_be_restored_missing_method obj = Object.new partial_mock = flexmock(obj) partial_mock.should_receive(:hi).with(1).once.and_return(:ok) partial_mock.should_receive(:hi).with(2).once.and_return(:ok) assert_equal :ok, obj.hi(1) assert_equal :ok, obj.hi(2) partial_mock.flexmock_teardown assert_raises(NoMethodError) { obj.hi } end def test_original_behavior_is_restored_when_multiple_methods_are_mocked dog = Dog.new flexmock(dog).should_receive(:bark).and_return(:grrrr) flexmock(dog).should_receive(:wag).and_return(:happy) flexmock(dog).flexmock_teardown assert_equal :woof, dog.bark assert_raises(NoMethodError) { dog.wag } end def test_original_behavior_is_restored_on_class_objects flexmock(Dog).should_receive(:create).once.and_return(:new_stub) assert_equal :new_stub, Dog.create flexmock(Dog).flexmock_teardown assert_equal :new_dog, Dog.create end def test_original_behavior_is_restored_on_singleton_methods obj = Object.new def obj.hi() :hello end flexmock(obj).should_receive(:hi).once.and_return(:hola) assert_equal :hola, obj.hi flexmock(obj).flexmock_teardown assert_equal :hello, obj.hi end def test_original_behavior_is_restored_on_singleton_methods_with_multiple_stubs obj = Object.new def obj.hi(n) "hello#{n}" end flexmock(obj).should_receive(:hi).with(1).once.and_return(:hola) flexmock(obj).should_receive(:hi).with(2).once.and_return(:hola) assert_equal :hola, obj.hi(1) assert_equal :hola, obj.hi(2) flexmock(obj).flexmock_teardown assert_equal "hello3", obj.hi(3) end def test_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubs flexmock(Dir).should_receive(:chdir).with("xx").once.and_return(:ok1) flexmock(Dir).should_receive(:chdir).with("yy").once.and_return(:ok2) assert_equal :ok1, Dir.chdir("xx") assert_equal :ok2, Dir.chdir("yy") flexmock(Dir).flexmock_teardown x = :not_called Dir.chdir("test") do assert_match %r{/test$}, Dir.pwd x = :called end assert_equal :called, x end def test_stubbing_file_shouldnt_break_writing flexmock(File).should_receive(:open).with("foo").once.and_return(:ok) assert_equal :ok, File.open("foo") flexmock(File).flexmock_teardown File.open("dummy.txt", "w") do |out| assert out.is_a?(IO) out.puts "XYZ" end text = File.open("dummy.txt") { |f| f.read } assert_equal "XYZ\n", text ensure FileUtils.rm_f("dummy.txt") end def test_original_behavior_is_restored_even_when_errors flexmock(Dog).should_receive(:create).once.and_return(:mock) begin flexmock_teardown rescue assertion_failed_error => _ nil end assert_equal :new_dog, Dog.create # Now disable the mock so that it doesn't cause errors on normal # test teardown m = flexmock(Dog).flexmock_get def m.flexmock_verify() end end def test_not_calling_stubbed_method_is_an_error dog = Dog.new flexmock(dog).should_receive(:bark).once assert_raises(assertion_failed_error) { flexmock(dog).flexmock_verify } dog.bark end def test_mock_is_verified_when_the_stub_is_verified obj = Object.new partial_mock = flexmock(obj) partial_mock.should_receive(:hi).once.and_return(:ok) assert_raises(assertion_failed_error) { partial_mock.flexmock_verify } end def test_stub_can_have_explicit_name obj = Object.new partial_mock = flexmock(obj, "Charlie") assert_equal "Charlie", partial_mock.flexmock_get.flexmock_name end def test_unamed_stub_will_use_default_naming_convention obj = Object.new partial_mock = flexmock(obj) assert_equal "flexmock(Object)", partial_mock.flexmock_get.flexmock_name end def test_partials_can_be_defined_in_a_block dog = Dog.new flexmock(dog) do |m| m.should_receive(:bark).and_return(:growl) end assert_equal :growl, dog.bark end def test_partials_defining_block_return_real_obj_not_proxy dog = flexmock(Dog.new) do |m| m.should_receive(:bark).and_return(:growl) end assert_equal :growl, dog.bark end def test_partial_mocks_always_return_domain_object dog = Dog.new assert_equal dog, flexmock(dog) assert_equal dog, flexmock(dog) { } end MOCK_METHOD_SUBSET = [ :should_receive, :new_instances, :flexmock_get, :flexmock_teardown, :flexmock_verify, ] def test_domain_objects_do_not_have_mock_methods dog = Dog.new MOCK_METHOD_SUBSET.each do |sym| assert ! dog.respond_to?(sym), "should not have :#{sym} defined" end end def test_partial_mocks_have_mock_methods dog = Dog.new flexmock(dog) MOCK_METHOD_SUBSET.each do |sym| assert dog.respond_to?(sym), "should have :#{sym} defined" end end def test_partial_mocks_do_not_have_mock_methods_after_teardown dog = Dog.new flexmock(dog) dog.flexmock_teardown MOCK_METHOD_SUBSET.each do |sym| assert ! dog.respond_to?(sym), "should not have :#{sym} defined" end end # This test ensures that singleton? does not use the old methods(false) # call that has fallen out of favor in Ruby 1.9. In multiple 1.9 releases # Delegator#methods will not even accept the optional argument, making flexmock # explode. Since there is a way to get singleton methods officially we might # as well just do it, right? class NoMethods def methods(arg = true) raise "Should not be called in the test lifecycle" end end def xtest_object_methods_method_is_not_used_in_singleton_checks obj = NoMethods.new def obj.mock() :original end flexmock(obj) end def test_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restored dog = Dog.new def dog.mock() :original end flexmock(dog) dog.flexmock_teardown assert_equal :original, dog.mock end class MockColision def mock :original end end def test_partial_mocks_with_mock_method_non_singleton_colision_have_original_defs_restored mc = MockColision.new flexmock(mc) mc.flexmock_teardown assert_equal :original, mc.mock end def test_safe_partial_mocks_do_not_support_mock_methods dog = Dog.new flexmock(:safe, dog) { } MOCK_METHOD_SUBSET.each do |sym| assert ! dog.respond_to?(sym), "should not have :#{sym} defined" end end def test_safe_partial_mocks_require_block dog = Dog.new assert_raises(FlexMock::UsageError) { flexmock(:safe, dog) } end def test_safe_partial_mocks_are_actually_mocked dog = flexmock(:safe, Dog.new) { |m| m.should_receive(:bark => :mocked) } assert_equal :mocked, dog.bark end def test_should_receive_does_not_override_preexisting_def dog = flexmock(DogPlus.new) assert_equal :dog_new, dog.new_instances assert_equal :dog_by_default, dog.by_default end def test_should_receive_does_override_should_receive_preexisting_def dog = flexmock(DogPlus.new) assert_kind_of FlexMock::CompositeExpectation, dog.should_receive(:x) end class Liar def respond_to?(method_name) sym = method_name.to_sym if sym == :not_defined true else super(method_name) end end end def test_liar_actually_lies liar = Liar.new assert liar.respond_to?(:not_defined) assert_raises(NoMethodError) { liar.not_defined } end def test_partial_mock_where_respond_to_is_true_yet_method_is_not_there liar = Liar.new flexmock(liar, :not_defined => :xyzzy) assert_equal :xyzzy, liar.not_defined end class MetaDog < Dog def method_missing(method, *args, &block) if method.to_s =~ /meow/ :meow else super end end def respond_to_missing?(method, *) method =~ /meow/ || super end end def test_partial_mock_where_method_created_by_method_missing_and_respond_to_missing dog = MetaDog.new flexmock(dog, :meow => :hiss) assert_equal :hiss, dog.meow end def test_partial_mocks_allow_stubbing_defined_methods_when_using_on dog = Dog.new flexmock(dog, :on, Dog) dog.should_receive(:bark).and_return(:grrr) assert_equal :grrr, dog.bark end def test_partial_mocks_disallow_stubbing_undefined_methods_when_using_on dog = Dog.new flexmock(dog, :on, Dog) assert_raises(NoMethodError, /meow.*explicitly/) do dog.should_receive(:meow).and_return(:something) end end # The following test was suggested by Pat Maddox for the RSpec # mocks. Evidently the (poorly implemented) == method caused issues # with RSpec Mock's internals. I'm just double checking for any # similar issues in FlexMock as well. class ValueObject attr_reader :val def initialize(val) @val = val end def ==(other) @val == other.val end end def test_partial_mocks_in_the_presense_of_equal_definition flexmock("existing obj", :foo => :foo) obj = ValueObject.new(:bar) flexmock(obj, :some_method => :some_method) end def test_partial_mocks_can_stub_methods_already_prepended_on_the_singleton_class m = Module.new { def foo; 10 end } obj = Class.new.new obj.singleton_class.class_eval { prepend m } flexmock(obj).should_receive(:foo).once.and_return(20) assert_equal 20, obj.foo end def test_partial_mocks_can_call_original_methods_already_prepended_on_the_singleton_class m = Module.new { def foo; 10 end } obj = Class.new.new obj.singleton_class.class_eval { prepend m } flexmock(obj).should_receive(:foo).once.pass_thru { |val| val * 3 } assert_equal 30, obj.foo end def test_partial_mocks_can_call_an_original_message_that_is_handled_by_method_missing obj = Class.new do attr_reader :mm_calls def initialize @mm_calls = Array.new end def method_missing(m, *args, &block) @mm_calls << [m, args, block] if m == :mm_handled_message args[0] * 10 + args[1] else super end end end.new flexmock(obj).should_receive(:mm_handled_message).with(10, 20).once.pass_thru assert_equal 120, obj.mm_handled_message(10, 20) assert_equal [[:mm_handled_message, [10, 20], nil]], obj.mm_calls end def test_partial_mocks_mentions_the_pass_thru_clause_when_passing_thru_to_a_non_handled_message obj = Class.new do attr_reader :mm_calls def initialize @mm_calls = Array.new end def method_missing(m, *args, &block) @mm_calls << [m, args, block] super end end.new flexmock(obj).should_receive(:does_not_exist).with(10, 20).once.pass_thru exception = assert_raises(NoMethodError) do obj.does_not_exist(10, 20) end assert(/pass_thru/ === exception.message, "expected #{exception.message} to mention the flexmock pass_thru clause") end def test_it_checks_whether_mocks_are_forbidden_before_forwarding_the_call obj = Class.new flexmock(obj).should_receive(:mocked).never result = FlexMock.forbid_mocking(tag = Object.new) do obj.mocked end assert_same result, tag end def test_inspect_on_mocked_method_can_successfully_call_a_mocked_method obj = Class.new do def inspect mocked(self) end end.new flexmock(obj).should_receive(:mocked).with(any).and_return("10") obj.inspect end def test_inspect_on_mocked_method_can_fail_at_calling_a_mocked_method obj = Class.new do def inspect mocked(self) end end.new flexmock(obj).should_receive(:mocked).never assert_raises(FlexMock::CheckFailedError) do obj.inspect end end end flexmock-2.0.4/test/record_mode_test.rb000066400000000000000000000074261263476550700202020ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class TestRecordMode < Minitest::Test include FlexMock::Minitest def test_recording_mode_works mock = flexmock("mock") mock.should_expect do |recorder| recorder.f { :answer } end assert_equal :answer, mock.f end def test_arguments_are_passed_to_recording_mode_block mock = flexmock("mock") mock.should_expect do |recorder| recorder.f(:arg) do |arg| assert_equal :arg, arg :answer end end assert_equal :answer, mock.f(:arg) end def test_recording_mode_handles_multiple_returns FlexMock.use("mock") do |mock| mock.should_expect do |r| answers = [1, 2] # HACK: The following lambda is needed in Ruby 1.9 to cause # the answers to be properly bound in the following block. lambda { } r.f { answers.shift } end assert_equal 1, mock.f assert_equal 2, mock.f end end def test_recording_mode_does_not_specify_order FlexMock.use("mock") do |mock| mock.should_expect do |r| r.f { 1 } r.g { 2 } end assert_equal 2, mock.g assert_equal 1, mock.f end end def test_recording_mode_gets_block_args_too mock = flexmock("mock") mock.should_expect do |r| r.f(1, Proc) { |arg, block| refute_nil block block.call } end assert_equal :block_result, mock.f(1) { :block_result } end def test_recording_mode_should_validate_args_with_equals assert_mock_failure(check_failed_error, :deep => true, :line => __LINE__+5) do FlexMock.use("mock") do |mock| mock.should_expect do |r| r.f(1) end mock.f(2) end end end def test_recording_mode_should_allow_arg_contraint_validation assert_mock_failure(check_failed_error, :deep => true, :line => __LINE__+5) do FlexMock.use("mock") do |mock| mock.should_expect do |r| r.f(1) end mock.f(2) end end end def test_recording_mode_should_handle_multiplicity_contraints assert_mock_failure(check_failed_error, :line => __LINE__+6) do FlexMock.use("mock") do |mock| mock.should_expect do |r| r.f { :result }.once end mock.f mock.f end end end def test_strict_record_mode_requires_exact_argument_matches assert_mock_failure(check_failed_error, :deep => true, :line => __LINE__+6) do FlexMock.use("mock") do |mock| mock.should_expect do |rec| rec.should_be_strict rec.f(Integer) end mock.f(3) end end end def test_strict_record_mode_requires_exact_ordering assert_mock_failure(check_failed_error, :deep => true, :line => __LINE__+8) do FlexMock.use("mock") do |mock| mock.should_expect do |rec| rec.should_be_strict rec.f(1) rec.f(2) end mock.f(2) mock.f(1) end end end def test_strict_record_mode_requires_once assert_mock_failure(check_failed_error, :deep => true, :line => __LINE__+7) do FlexMock.use("mock") do |mock| mock.should_expect do |rec| rec.should_be_strict rec.f(1) end mock.f(1) mock.f(1) end end end def test_strict_record_mode_can_not_fail FlexMock.use("mock") do |mock| mock.should_expect do |rec| rec.should_be_strict rec.f(Integer) rec.f(2) end mock.f(Integer) mock.f(2) end end end flexmock-2.0.4/test/redirect_error.rb000066400000000000000000000004211263476550700176570ustar00rootroot00000000000000require 'stringio' class FlexMock module RedirectError def redirect_error require 'stringio' old_err = $stderr $stderr = StringIO.new yield $stderr.string ensure $stderr = old_err end private :redirect_error end end flexmock-2.0.4/test/rspec_integration/000077500000000000000000000000001263476550700200425ustar00rootroot00000000000000flexmock-2.0.4/test/rspec_integration/integration_spec.rb000077500000000000000000000027041263476550700237320ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ if defined?(RSpec) RSpec.configure do |config| config.mock_with :flexmock end else Spec::Runner.configure do |config| config.mock_with :flexmock end end describe "FlexMock in a RSpec example" do specify "should be able to create a mock" do m = flexmock() end specify "should have an error when a mock is not called" do m = flexmock("Expectation Failured") m.should_receive(:hi).with().once lambda { flexmock_verify }.should raise_error(RSpec::Expectations::ExpectationNotMetError, /\bhi\b.*incorrect.*times/i) end specify "should be able to create a stub" do s = "Hello World" flexmock(:base, s).should_receive(:downcase).with().once.and_return("hello WORLD") s.downcase.should == "hello WORLD" end specify "Should show an example failure" do lambda { 1.should == 2 }.should raise_error(RSpec::Expectations::ExpectationNotMetError, /expected: 2.*got: 1/m) end specify "Should show how mocks are displayed in error messages" do m = flexmock("x") lambda { m.should == 2 }.should raise_error(RSpec::Expectations::ExpectationNotMetError, /got: /) end end flexmock-2.0.4/test/rspec_integration/spy_example_spec.rb000066400000000000000000000122061263476550700237300ustar00rootroot00000000000000require 'flexmock/rspec' RSpec.configure do |config| config.mock_with :flexmock end describe "Dog" do class Dog def wags(arg) fail "SHOULD NOT BE CALLED" end def barks fail "SHOULD NOT BE CALLED" end end let(:dog) { flexmock(:on, Dog) } context "single calls with arguments" do before do dog.wags(:tail) end it "accepts no with" do dog.should have_received(:wags) end it "accepts with restriction" do dog.should have_received(:wags).with(:tail) end it "accepts not methods called" do dog.should_not have_received(:bark) end it "rejects incorrect with restriction" do should_fail(/^expected wag\(:foot\) to be received by /i) do dog.should have_received(:wag).with(:foot) end end it "rejects not on correct matcher" do should_fail(/^expected wags\(:tail\) to NOT be received by /i) do dog.should_not have_received(:wags).with(:tail) end end end context "multiple calls with multiple arguments" do before do dog.wags(:tail) dog.wags(:tail) dog.wags(:tail) dog.wags(:head, :tail) dog.barks dog.barks end it "accepts wags(:tail) multiple times" do dog.should have_received(:wags).with(:tail).times(3) end it "rejects wags(:tail) wrong times value" do should_fail(/^expected wags\(:tail\) to be received by /i) do dog.should have_received(:wags).with(:tail).times(2) end end it "detects any_args" do dog.should have_received(:wags).times(4) end it "accepts once" do dog.should have_received(:wags).with(:head, :tail).once end it "rejects an incorrect once" do should_fail(/^expected wags\(:tail\) to be received by once/i) do dog.should have_received(:wags).with(:tail).once end end it "accepts twice" do dog.should have_received(:barks).twice end it "rejects an incorrect twice" do should_fail(/^expected wags\(:tail\) to be received by twice/) do dog.should have_received(:wags).with(:tail).twice end end it "accepts never" do dog.should have_received(:jump).never end it "rejects an incorrect never" do should_fail(/^expected barks\(\) to be received by never/i) do dog.should have_received(:barks).with().never end end it "rejects an incorrect never" do dog.should_not have_received(:jump) end end context "with additional validations" do it "accepts when correct" do dog.wags(:tail) dog.should have_received(:wags).and { |arg| arg.should == :tail } end it "rejects when incorrect" do dog.wags(:tail) should_fail(/expected: :foot.*got: :tail/im) do dog.should have_received(:wags).and { |arg| arg.should == :foot } end end it "rejects on all calls" do dog.wags(:foot) dog.wags(:foot) dog.wags(:tail) should_fail(/expected: :foot.*got: :tail/im) do dog.should have_received(:wags).and { |arg| arg.should == :foot } end end it "runs the first additional block" do dog.wags(:tail) should_fail(/expected: :foot.*got: :tail/im) do dog.should have_received(:wags).and { |args| args.should == :foot }.and { |args| args.should == :tail } end end it "runs the second additional block" do dog.wags(:tail) should_fail(/expected: :foot.*got: :tail/im) do dog.should have_received(:wags).and { |args| args.should == :tail }.and { |args| args.should == :foot } end end end context "with ordinal constraints" do it "detects the first call" do dog.wags(:tail) dog.wags(:foot) dog.should have_received(:wags).and { |arg| arg.should == :tail }.on(1) end it "detects the second call" do dog.wags(:tail) dog.wags(:foot) dog.should have_received(:wags).and { |arg| arg.should == :foot }.on(2) end end context "with blocks" do before do dog.wags { } dog.barks end it "accepts wags with a block" do dog.should have_received(:wags).with_a_block dog.should have_received(:wags) end it "accepts barks without a block" do dog.should have_received(:barks).without_a_block dog.should have_received(:barks) end it "rejects wags without a block" do should_fail(/without a block/) do dog.should have_received(:wags).without_a_block end end it "rejects barks with a block" do should_fail(/with a block/) do dog.should have_received(:barks).with_a_block end end end def should_fail(message_pattern) failed = false begin yield rescue RSpec::Expectations::ExpectationNotMetError => ex failed = true ex.message.should match(message_pattern) end RSpec::Expectations.fail_with "Expected block to fail with message #{message_pattern.inspect}, no failure detected" unless failed end end flexmock-2.0.4/test/samples_test.rb000066400000000000000000000150371263476550700173610ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' # Sample FlexMock Usage. class TestSamples < Minitest::Test include FlexMock::Minitest # This is a basic example where we setup a mock object to mimic an # IO object. We know that the +count_lines+ method uses gets, so we # tell the mock object to handle +gets+ by returning successive # elements of an array (just as the real +gets+ returns successive # elements of a file. def test_file_io mock_file = flexmock("file") mock_file.should_receive(:gets).and_return("line 1", "line 2", nil) assert_equal 2, count_lines(mock_file) end # Count the number of lines in a file. Used in the test_file_io # test. def count_lines(file) n = 0 while file.gets n += 1 end n end end class TestUndefined < Minitest::Test include FlexMock::Minitest def test_undefined_values m = flexmock("mock") m.should_receive(:divide_by).with(0). and_return_undefined assert_equal FlexMock.undefined, m.divide_by(0) end end class TestSimple < Minitest::Test include FlexMock::Minitest def test_simple_mock m = flexmock(:pi => 3.1416, :e => 2.71) assert_equal 3.1416, m.pi assert_equal 2.71, m.e end end class TestDog < Minitest::Test include FlexMock::Minitest def test_dog_wags tail_mock = flexmock(:wag => :happy) assert_equal :happy, tail_mock.wag end end class Woofer end class Dog def initialize @woofer = Woofer.new end def bark @woofer.woof end def wag :happy end end class TestDogBarking < Minitest::Test include FlexMock::Minitest # Setup the tests by mocking the +new+ method of # Woofer and return a mock woofer. def setup @dog = Dog.new flexmock(@dog, :bark => :grrr) end def test_dog assert_equal :grrr, @dog.bark # Mocked Method assert_equal :happy, @dog.wag # Normal Method end end class TestDogBarkingWithNewInstances < Minitest::Test include FlexMock::Minitest # Setup the tests by mocking Woofer to always # return partial mocks. def setup flexmock(Woofer).new_instances.should_receive(:woof => :grrr) end def test_dog assert_equal :grrr, Dog.new.bark # All dog objects assert_equal :grrr, Dog.new.bark # are mocked. end end class TestDefaults < Minitest::Test include FlexMock::Minitest def setup @mock_dog = flexmock("Fido") @mock_dog.should_receive(:tail => :a_tail, :bark => "woof").by_default end def test_something_where_bark_must_be_called_once @mock_dog.should_receive(:bark => "bow wow").once assert_equal "bow wow", @mock_dog.bark assert_equal :a_tail, @mock_dog.tail end end class TestDemeter < Minitest::Test include FlexMock::Minitest def test_manual_mocking # Manually mocking a Law of Demeter violation cog = flexmock("cog") cog.should_receive(:turn).once.and_return(:ok) joint = flexmock("gear", :cog => cog) axle = flexmock("axle", :universal_joint => joint) chassis = flexmock("chassis", :axle => axle) car = flexmock("car", :chassis => chassis) # test code assert_equal :ok, car.chassis.axle.universal_joint.cog.turn end def test_demeter car = flexmock("car") car.should_receive( "chassis.axle.universal_joint.cog.turn" => :ok).once # Test code assert_equal :ok, car.chassis.axle.universal_joint.cog.turn end end class TestDb < Minitest::Test include FlexMock::Minitest def test_db db = flexmock('db') db.should_receive(:query).and_return([1,2,3]) db.should_receive(:update).with(5).and_return(nil).once # test code assert_nil db.update(5) end end class TestDb < Minitest::Test include FlexMock::Minitest def test_query_and_update db = flexmock('db') db.should_receive(:query).and_return([1,2,3]).ordered db.should_receive(:update).and_return(nil).ordered # test code here assert_raises(check_failed_error) do db.update db.query end end def test_ordered_queries db = flexmock('db') db.should_receive(:startup).once.ordered db.should_receive(:query).with("CPWR").and_return(12.3). once.ordered(:queries) db.should_receive(:query).with("MSFT").and_return(10.0). once.ordered(:queries) db.should_receive(:query).with(/^....$/).and_return(3.3). at_least.once.ordered(:queries) db.should_receive(:finish).once.ordered # test code here db.startup db.query("CPWR") db.query("MSFT") db.query("asdf") db.finish end def test_ordered_queries_in_record_mode db = flexmock('db') db.should_expect do |rec| rec.startup.once.ordered rec.query("CPWR") { 12.3 }.once.ordered(:queries) rec.query("MSFT") { 10.0 }.once.ordered(:queries) rec.query(/^....$/) { 3.3 }.at_least.once.ordered(:queries) rec.finish.once.ordered end # test code here using +db+. db.startup db.query("CPWR") db.query("MSFT") db.query("asdf") db.finish end def known_good_way_to_build_xml(builder) builder.html end def new_way_to_build_xml(builder) known_good_way_to_build_xml(builder) end def test_build_xml builder = flexmock('builder') builder.should_expect do |rec| rec.should_be_strict known_good_way_to_build_xml(rec) # record the messages end new_way_to_build_xml(builder) # compare to new way end end class TestMoreSamples < Minitest::Test include FlexMock::Minitest def test_multiple_gets file = flexmock('file') file.should_receive(:gets).with_no_args. and_return("line 1\n", "line 2\n") # test code here assert_equal "line 1\n", file.gets assert_equal "line 2\n", file.gets end def test_an_important_message m = flexmock('m') m.should_receive(:an_important_message).and_return(1).once m.should_ignore_missing # test code here assert_equal 1, m.an_important_message assert_equal FlexMock.undefined, m.other end class QuoteService end class Portfolio def initialize @quote_service = QuoteService.new end def value @quote_service.quote end end def test_portfolio_value flexmock(QuoteService).new_instances do |m| m.should_receive(:quote).and_return(100) end port = Portfolio.new value = port.value # Portfolio calls QuoteService.quote assert_equal 100, value end end flexmock-2.0.4/test/should_ignore_missing_test.rb000066400000000000000000000042721263476550700223060ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' class TestShouldIgnoreMissing < Minitest::Test include FlexMock::Minitest def setup @mock = flexmock("mock") end def test_mocks_do_not_respond_to_undefined_methods assert !@mock.respond_to?(:unknown_foo) end def test_mocks_do_respond_to_defined_methods @mock.should_receive(:known_foo => :bar) assert @mock.respond_to?(:known_foo) end def test_mocks_do_respond_to_any_method_when_ignoring_missing @mock.should_ignore_missing assert @mock.respond_to?(:unknown_foo) end def test_should_ignore_missing_returns_mock result = @mock.should_ignore_missing assert_equal result, @mock end def test_ignored_methods_return_undefined @mock.should_ignore_missing assert_equal FlexMock.undefined, @mock.unknown_foo @mock.unknown_foo.bar.baz.bleep end def test_undefined_mocking_with_arguments @mock.should_ignore_missing assert_equal FlexMock.undefined, @mock.xyzzy(1,:two,"three") end def test_method_chains_with_undefined_are_self_preserving @mock.should_ignore_missing assert_equal FlexMock.undefined, @mock.a.b.c.d.e.f(1).g.h.i.j end def test_method_proc_raises_error_on_unknown assert_raises(NameError) { @mock.method(:unknown_foo) } end def test_method_returns_callable_proc @mock.should_receive(:known_foo).once method_proc = @mock.method(:known_foo) refute_nil method_proc method_proc.call([]) end def test_not_calling_method_proc_will_fail_count_constraints @mock.should_receive(:known_foo).once method_proc = @mock.method(:known_foo) refute_nil method_proc assert_raises assertion_failed_error do flexmock_teardown end end def test_method_returns_do_nothing_proc_for_missing_methods @mock.should_ignore_missing method_proc = @mock.method(:plugh) refute_nil method_proc assert_equal FlexMock.undefined, method_proc.call end end flexmock-2.0.4/test/should_receive_test.rb000066400000000000000000001007061263476550700207130ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' def mock_top_level_function :mtlf end module Kernel def mock_kernel_function :mkf end end # Used for testing class Cat def purr end def meow end end class TestFlexMockShoulds < Minitest::Test include FlexMock::Minitest # Expected error messages on failures COUNT_ERROR_MESSAGE = /\bcalled\s+incorrect\s+number\s+of\s+times\b/ NO_MATCH_ERROR_MESSAGE = /\bno\s+matching\s+handler\b/ AT_LEAST_ERROR_MESSAGE = COUNT_ERROR_MESSAGE AT_MOST_ERROR_MESSAGE = COUNT_ERROR_MESSAGE OUT_OF_ORDER_ERROR_MESSAGE = /\bcalled\s+out\s+of\s+order\b/ NON_CONTAINER_MESSAGE = /\bis\s+not\s+in\s+a\s+container\b/ def test_defaults FlexMock.use do |m| m.should_receive(:hi) assert_nil m.hi assert_nil m.hi(1) assert_nil m.hi("hello", 2) end end def test_returns_with_value FlexMock.use do |m| m.should_receive(:hi).returns(1) assert_equal 1, m.hi assert_equal 1, m.hi(123) end end def test_returns_with_multiple_values FlexMock.use do |m| m.should_receive(:hi).and_return(1,2,3) assert_equal 1, m.hi assert_equal 2, m.hi assert_equal 3, m.hi assert_equal 3, m.hi assert_equal 3, m.hi end end def test_multiple_returns FlexMock.use do |m| m.should_receive(:hi).and_return(1).and_return(2,3) assert_equal 1, m.hi assert_equal 2, m.hi assert_equal 3, m.hi assert_equal 3, m.hi assert_equal 3, m.hi end end def test_returns_with_block FlexMock.use do |m| result = nil m.should_receive(:hi).with(Object).returns { |obj| result = obj } m.hi(3) assert_equal 3, result end end def test_block_example_from_readme FlexMock.use do |m| m.should_receive(:foo).with(Integer,Proc).and_return(:got_block) m.should_receive(:foo).with(Integer).and_return(:no_block) assert_equal :no_block, m.foo(1) assert_equal :got_block, m.foo(1) { } end end def test_return_with_and_without_block_interleaved FlexMock.use do |m| m.should_receive(:hi).and_return(:a).and_return { :b }.and_return(:c) assert_equal :a, m.hi assert_equal :b, m.hi assert_equal :c, m.hi assert_equal :c, m.hi end end def test_and_returns_alias FlexMock.use do |m| m.should_receive(:hi).and_return(4) assert_equal 4, m.hi end end def test_and_return_undefined FlexMock.use do |m| m.should_receive(:foo).and_return_undefined m.should_receive(:phoo).returns_undefined assert_equal FlexMock.undefined, m.foo assert_equal FlexMock.undefined, m.foo.bar.baz.bing.ka_ching assert_equal FlexMock.undefined, m.phoo.bar.baz.bing.ka_ching end end def test_and_yield_will_continue_to_yield_the_same_value FlexMock.use do |m| m.should_receive(:hi).and_yield(:yield_value) assert_equal :yield_value, m.hi { |v| v } assert_equal :yield_value, m.hi { |v| v } end end def test_and_yield_with_multiple_values_yields_the_values FlexMock.use do |m| m.should_receive(:hi).and_yield(:one, :two).once assert_equal [:one, :two], m.hi { |a, b| [a, b] } end end def test_multiple_yields_are_done_sequentially FlexMock.use do |m| m.should_receive(:msg).and_yield(:one).and_yield(:two) assert_equal :one, m.msg { |a| a } assert_equal :two, m.msg { |a| a } assert_equal :two, m.msg { |a| a } end end def test_multiple_yields_and_multiple_returns_are_synced FlexMock.use do |m| m.should_receive(:msg).and_yield(:one).and_return(1).and_yield(:two).and_return(2) yielded_values = [] returned_values = [] returned_values << m.msg { |a| yielded_values << a } returned_values << m.msg { |a| yielded_values << a } returned_values << m.msg { |a| yielded_values << a } assert_equal [:one, :two, :two], yielded_values assert_equal [1, 2, 2], returned_values end end def test_failure_if_no_block_given FlexMock.use do |m| m.should_receive(:hi).and_yield(:one, :two).once assert_raises(FlexMock::MockError) do m.hi end end end def test_failure_different_return_value_than_yield_return FlexMock.use do |m| m.should_receive(:hi).and_yield(:yld).once.and_return(:ret) yielded_value = nil assert_equal :ret, m.hi { |v| yielded_value = v } assert_equal :yld, yielded_value end end def test_multiple_yields FlexMock.use do |m| m.should_receive(:hi).and_yield(:one, :two).and_yield(1, 2) assert_equal [:one, :two], m.hi { |a, b| [a, b] } assert_equal [1, 2], m.hi { |a, b| [a, b] } end end def test_multiple_yields_will_yield_the_last_value_set FlexMock.use do |m| m.should_receive(:hi).and_yield(:a).and_yield(:b) assert_equal [:a], m.hi { |a, b| [a] } assert_equal [:b], m.hi { |a, b| [a] } assert_equal [:b], m.hi { |a, b| [a] } assert_equal [:b], m.hi { |a, b| [a] } assert_equal [:b], m.hi { |a, b| [a] } end end def test_yielding_then_not_yielding_and_then_yielding_again FlexMock.use do |m| m.should_receive(:hi).and_yield(:a).once m.should_receive(:hi).and_return(:b).once m.should_receive(:hi).and_yield(:c).once assert_equal :a, m.hi { |v| v } assert_equal :b, m.hi assert_equal :c, m.hi { |v| v } end end def test_yields_syntax FlexMock.use do |m| m.should_receive(:hi).yields(:one) assert_equal :one, m.hi { |a| a } end end class MyError < RuntimeError end def test_and_raises_with_exception_class_throws_exception FlexMock.use do |m| m.should_receive(:failure).and_raise(MyError) assert_raises MyError do m.failure end end end def test_and_raises_with_arguments_throws_exception_made_with_args FlexMock.use do |m| m.should_receive(:failure).and_raise(MyError, "my message") ex = assert_raises MyError do m.failure end assert_equal "my message", ex.message end end def test_and_raises_with_a_specific_exception_throws_the_exception FlexMock.use do |m| err = MyError.new m.should_receive(:failure).and_raise(err) ex = assert_raises MyError do m.failure end assert_equal err, ex end end def test_raises_is_an_alias_for_and_raise FlexMock.use do |m| m.should_receive(:failure).raises(RuntimeError) assert_raises RuntimeError do m.failure end end end def test_multiple_and_raise_clauses_will_be_done_sequentially FlexMock.use do |m| m.should_receive(:failure). and_raise(RuntimeError, "ONE"). and_raise(RuntimeError, "TWO") ex = assert_raises RuntimeError do m.failure end assert_equal "ONE", ex.message ex = assert_raises RuntimeError do m.failure end assert_equal "TWO", ex.message end end def test_and_throw_will_throw_a_symbol FlexMock.use do |m| m.should_receive(:msg).and_throw(:sym) value = catch(:sym) do m.msg fail "Should not reach this line" end assert_nil value end end def test_and_throw_with_expression_will_throw FlexMock.use do |m| m.should_receive(:msg).and_throw(:sym, :return_value) value = catch(:sym) do m.msg fail "Should not reach this line" end assert_equal :return_value, value end end def test_throws_is_an_alias_for_and_throw FlexMock.use do |m| m.should_receive(:msg).throws(:sym, :return_value) value = catch(:sym) do m.msg fail "Should not reach this line" end assert_equal :return_value, value end end def test_multiple_throws_will_be_done_sequentially FlexMock.use do |m| m.should_receive(:toss). and_throw(:sym, "ONE"). and_throw(:sym, "TWO") value = catch(:sym) do m.toss end assert_equal "ONE", value value = catch(:sym) do m.toss end assert_equal "TWO", value end end def test_pass_thru_just_returns_undefined_on_mocks FlexMock.use do |m| m.should_receive(:hi).pass_thru assert_equal FlexMock.undefined, m.hi end end def test_multiple_expectations FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10) m.should_receive(:hi).with(2).returns(20) assert_equal 10, m.hi(1) assert_equal 20, m.hi(2) end end def test_with_no_args_with_no_args FlexMock.use do |m| m.should_receive(:hi).with_no_args m.hi end end def test_with_no_args_but_with_args assert_mock_failure(check_failed_error, :message =>NO_MATCH_ERROR_MESSAGE, :deep => true) do FlexMock.use do |m| m.should_receive(:hi).with_no_args m.hi(1) end end end def test_with_any_args FlexMock.use do |m| m.should_receive(:hi).with_any_args m.hi m.hi(1) m.hi(1,2,3) m.hi("this is a test") end end def test_with_any_single_arg_matching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(1,FlexMock.any).twice m.hi(1,2) m.hi(1, "this is a test") end end def test_with_any_single_arg_nonmatching FlexMock.use('greeter') do |m| m.should_receive(:hi).times(3) m.should_receive(:hi).with(1,FlexMock.any).never m.hi m.hi(1) m.hi(1, "hi", nil) end end def test_with_equal_arg_matching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(FlexMock.eq(Object)).once m.hi(Object) end end def test_with_ducktype_arg_matching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(FlexMock.ducktype(:purr, :meow)).once m.hi(Cat.new) end end def test_with_ducktype_arg_matching_no_match FlexMock.use('greeter') do |m| m.should_receive(:hi).with(FlexMock.ducktype(:purr, :meow, :growl)) assert_mock_failure(check_failed_error, :deep => true, :line => __LINE__+1) { m.hi(Cat.new) } end end def test_with_hash_matching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(FlexMock.hsh(:a => 1, :b => 2)).once m.hi(:a => 1, :b => 2, :c => 3) end end def test_with_hash_non_matching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(FlexMock.hsh(:a => 1, :b => 2)) assert_mock_failure(check_failed_error, :deep => true, :line => __LINE__+1) { m.hi(:a => 1, :b => 4, :c => 3) } end end def test_with_equal_arg_nonmatching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(FlexMock.eq(Object)).never m.should_receive(:hi).never m.should_receive(:hi).with(1).once m.hi(1) end end def test_with_optional_proc FlexMock.use('greeter') do |m| m.should_receive(:hi).with(optional_proc).once m.hi { } end end def test_with_optional_proc_and_missing_proc FlexMock.use('greeter') do |m| m.should_receive(:hi).with(optional_proc).once m.hi end end def test_with_optional_proc_distinquishes_between_nil_and_missing FlexMock.use('greeter') do |m| m.should_receive(:hi).with(optional_proc).never m.should_receive(:hi).with(nil).once m.hi(nil) end end def test_with_arbitrary_arg_matching FlexMock.use('greeter') do |m| m.should_receive(:hi).with(FlexMock.on { |arg| arg % 2 == 0 rescue nil }).twice m.should_receive(:hi).never m.should_receive(:hi).with(1).once m.should_receive(:hi).with(2).never m.should_receive(:hi).with(3).once m.should_receive(:hi).with(4).never m.hi(1) m.hi(2) m.hi(3) m.hi(4) end end def test_args_matching_with_regex FlexMock.use do |m| m.should_receive(:hi).with(/one/).returns(10) m.should_receive(:hi).with(/t/).returns(20) assert_equal 10, m.hi("one") assert_equal 10, m.hi("done") assert_equal 20, m.hi("two") assert_equal 20, m.hi("three") end end def test_arg_matching_with_regex_matching_non_string FlexMock.use do |m| m.should_receive(:hi).with(/1/).returns(10) assert_equal 10, m.hi(319) end end def test_arg_matching_with_class FlexMock.use do |m| m.should_receive(:hi).with(Fixnum).returns(10) m.should_receive(:hi).with(Object).returns(20) assert_equal 10, m.hi(319) assert_equal 10, m.hi(Fixnum) assert_equal 20, m.hi("hi") end end def test_arg_matching_with_no_match FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10) assert_mock_failure(check_failed_error, :message =>NO_MATCH_ERROR_MESSAGE, :deep => true, :line => __LINE__+1) { m.hi(2) } end end def test_arg_matching_with_string_doesnt_over_match FlexMock.use do |m| m.should_receive(:hi).with(String).returns(20) assert_mock_failure(check_failed_error, :message =>NO_MATCH_ERROR_MESSAGE, :deep => true, :line => __LINE__+1) { m.hi(1.0) } end end def test_block_arg_given_to_no_args FlexMock.use do |m| m.should_receive(:hi).with_no_args.returns(20) assert_mock_failure(check_failed_error, :message =>NO_MATCH_ERROR_MESSAGE, :deep => true, :line => __LINE__+1) { m.hi { 1 } } end end def test_block_arg_given_to_matching_proc FlexMock.use do |m| arg = nil m.should_receive(:hi).with(Proc).once. and_return { |block| arg = block; block.call } result = m.hi { 1 } assert_equal 1, arg.call assert_equal 1, result end end def test_arg_matching_precedence_when_best_first FlexMock.use("greeter") do |m| m.should_receive(:hi).with(1).once m.should_receive(:hi).with(FlexMock.any).never m.hi(1) end end def test_arg_matching_precedence_when_best_last_but_still_matches_first FlexMock.use("greeter") do |m| m.should_receive(:hi).with(FlexMock.any).once m.should_receive(:hi).with(1).never m.hi(1) end end def test_never_and_never_called FlexMock.use do |m| m.should_receive(:hi).with(1).never end end def test_never_and_called_once assert_mock_failure(check_failed_error, :message =>COUNT_ERROR_MESSAGE, :deep => true, :line => __LINE__+3) do FlexMock.use do |m| m.should_receive(:hi).with(1).never m.hi(1) end end end def test_once_called_once FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).once m.hi(1) end end def test_once_but_never_called assert_mock_failure(assertion_failed_error, :message =>COUNT_ERROR_MESSAGE, :line => __LINE__+2) do FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).once end end end def test_once_but_called_twice assert_mock_failure(check_failed_error, :message =>COUNT_ERROR_MESSAGE, :line => __LINE__+4) do FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).once m.hi(1) m.hi(1) end end end def test_twice_and_called_twice FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).twice m.hi(1) m.hi(1) end end def test_zero_or_more_called_zero FlexMock.use do |m| m.should_receive(:hi).zero_or_more_times end end def test_zero_or_more_called_once FlexMock.use do |m| m.should_receive(:hi).zero_or_more_times m.hi end end def test_zero_or_more_called_100 FlexMock.use do |m| m.should_receive(:hi).zero_or_more_times 100.times { m.hi } end end def test_times FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).times(10) 10.times { m.hi(1) } end end def test_at_least_called_once FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once m.hi(1) end end def test_at_least_but_never_called assert_mock_failure(assertion_failed_error, :message =>AT_LEAST_ERROR_MESSAGE, :line => __LINE__+2) do FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once end end end def test_at_least_once_but_called_twice FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once m.hi(1) m.hi(1) end end def test_at_least_and_exact assert_mock_failure(check_failed_error, :message =>COUNT_ERROR_MESSAGE, :line => __LINE__+4) do FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once.once m.hi(1) m.hi(1) end end end def test_at_most_but_never_called FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_most.once end end def test_at_most_called_once FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_most.once m.hi(1) end end def test_at_most_called_twice ex = assert_mock_failure(check_failed_error, :message =>AT_MOST_ERROR_MESSAGE, :line => __LINE__+4) do FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_most.once m.hi(1) m.hi(1) end end assert_match(/at most 1/i, ex.message) end def test_at_most_and_at_least_called_never ex = assert_mock_failure(assertion_failed_error, :message =>AT_LEAST_ERROR_MESSAGE, :line => __LINE__+2) do FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice end end assert_match(/at least 1/i, ex.message) end def test_at_most_and_at_least_called_once FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice m.hi(1) end end def test_at_most_and_at_least_called_twice FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice m.hi(1) m.hi(1) end end def test_at_most_and_at_least_called_three_times assert_mock_failure(check_failed_error, :message =>AT_MOST_ERROR_MESSAGE, :line => __LINE__+5) do FlexMock.use do |m| m.should_receive(:hi).with(1).returns(10).at_least.once.at_most.twice m.hi(1) m.hi(1) m.hi(1) end end end def test_call_counts_only_apply_to_matching_args FlexMock.use do |m| m.should_receive(:hi).with(1).once m.should_receive(:hi).with(2).twice m.should_receive(:hi).with(3) m.hi(1) m.hi(2) m.hi(2) 20.times { m.hi(3) } end end def test_call_counts_only_apply_to_matching_args_with_mismatch ex = assert_mock_failure(assertion_failed_error, :message =>COUNT_ERROR_MESSAGE, :line => __LINE__+3) do FlexMock.use do |m| m.should_receive(:hi).with(1).once m.should_receive(:hi).with(2).twice m.should_receive(:hi).with(3) m.should_receive(:lo) m.hi(1) m.hi(2) m.lo 20.times { m.hi(3) } end end assert_match(/hi\(2\)/, ex.message) end def test_ordered_calls_in_order_will_pass FlexMock.use 'm' do |m| m.should_receive(:hi).ordered m.should_receive(:lo).ordered m.hi m.lo end end def test_ordered_calls_out_of_order_will_fail assert_mock_failure(check_failed_error, :message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use 'm' do |m| m.should_receive(:hi).ordered m.should_receive(:lo).ordered m.lo m.hi end end end def test_failure_in_ordered_calls_combined_with_valid_count_will_report_an_order_failure assert_mock_failure(check_failed_error, :message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use 'm', 'n' do |m, n| m.should_receive(:hi).once.globally.ordered n.should_receive(:lo).once.globally.ordered n.lo m.hi end end end def test_order_calls_with_different_arg_lists_and_in_order_will_pass FlexMock.use 'm' do |m| m.should_receive(:hi).with("one").ordered m.should_receive(:hi).with("two").ordered m.hi("one") m.hi("two") end end def test_order_calls_with_different_arg_lists_and_out_of_order_will_fail assert_mock_failure(check_failed_error, :message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use 'm' do |m| m.should_receive(:hi).with("one").ordered m.should_receive(:hi).with("two").ordered m.hi("two") m.hi("one") end end end def test_unordered_calls_do_not_effect_ordered_testing FlexMock.use 'm' do |m| m.should_receive(:blah) m.should_receive(:hi).ordered m.should_receive(:lo).ordered m.blah m.hi m.blah m.lo m.blah end end def test_ordered_with_multiple_calls_will_pass FlexMock.use 'm' do |m| m.should_receive(:hi).ordered m.should_receive(:lo).ordered m.hi m.hi m.lo m.lo end end def test_grouped_ordering_with_numbers FlexMock.use 'm' do |m| m.should_receive(:start).ordered(1) m.should_receive(:flip).ordered(2) m.should_receive(:flop).ordered(2) m.should_receive(:final).ordered m.start m.flop m.flip m.flop m.final end end def test_grouped_ordering_with_symbols FlexMock.use 'm' do |m| m.should_receive(:start).ordered(:start_group) m.should_receive(:flip).ordered(:flip_flop_group) m.should_receive(:flop).ordered(:flip_flop_group) m.should_receive(:final).ordered m.start m.flop m.flip m.flop m.final end end def test_global_ordering_message_includes_received_calls e = assert_mock_failure(check_failed_error, :message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use 'm' do |m| one = m.should_receive(:one).globally.ordered two = m.should_receive(:two).globally.ordered m.one m.two m.one end end assert_match /one\(\) matched by should_receive\(:one\)/, e.message assert_match /two\(\) matched by should_receive\(:two\)/, e.message assert_match /one\(\) matched by should_receive\(:one\)/, e.message end def test_ordering_message_includes_received_calls e = assert_mock_failure(check_failed_error, :message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use 'm' do |m| one = m.should_receive(:one).ordered two = m.should_receive(:two).ordered m.one m.two m.one end end assert_match /one\(\) matched by should_receive\(:one\)/, e.message assert_match /two\(\) matched by should_receive\(:two\)/, e.message assert_match /one\(\) matched by should_receive\(:one\)/, e.message end def test_explicit_ordering_mixed_with_implicit_ordering_should_not_overlap FlexMock.use 'm' do |m| xstart = m.should_receive(:start).ordered xmid = m.should_receive(:mid).ordered(:group_name) xend = m.should_receive(:end).ordered assert xstart.order_number < xmid.order_number assert xmid.order_number < xend.order_number end end def test_explicit_ordering_with_explicit_misorders assert_mock_failure(check_failed_error, :message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use 'm' do |m| m.should_receive(:hi).ordered(:first_group) m.should_receive(:lo).ordered(:second_group) m.lo m.hi end end # TODO: It would be nice to get the group names in the error message. # assert_match /first_group/, ex.message # assert_match /second_group/, ex.message end # Test submitted by Mikael Pahmp to correct expectation matching. def test_ordering_with_explicit_no_args_matches_correctly FlexMock.use("m") do |m| m.should_receive(:foo).with_no_args.once.ordered m.should_receive(:bar).with_no_args.once.ordered m.should_receive(:foo).with_no_args.once.ordered m.foo m.bar m.foo end end # Test submitted by Mikael Pahmp to correct expectation matching. def test_ordering_with_any_arg_matching_correctly_matches FlexMock.use("m") do |m| m.should_receive(:foo).with_any_args.once.ordered m.should_receive(:bar).with_any_args.once.ordered m.should_receive(:foo).with_any_args.once.ordered m.foo m.bar m.foo end end def test_ordering_between_mocks_is_not_normally_defined FlexMock.use("x", "y") do |x, y| x.should_receive(:one).ordered y.should_receive(:two).ordered y.two x.one end end def test_ordering_between_mocks_is_honored_for_global_ordering assert_mock_failure(check_failed_error, :message =>OUT_OF_ORDER_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use("x", "y") do |x, y| x.should_receive(:one).globally.ordered y.should_receive(:two).globally.ordered y.two x.one end end end def test_ordering_is_verified_after_eligibility assert_mock_failure(check_failed_error, :message =>COUNT_ERROR_MESSAGE, :deep => true, :line => __LINE__+6) do FlexMock.use("x", "y") do |x, y| x.should_receive(:one).once.ordered x.should_receive(:two).ordered x.one x.two x.one end end end def test_expectation_formating mock = flexmock("m") exp = mock.should_receive(:f).with(1,"two", /^3$/). and_return(0).at_least.once mock.f(1, "two", 3) assert_equal 'f(1, "two", /^3$/)', exp.to_s end def test_multi_expectation_formatting mock = flexmock("mock") exp = mock.should_receive(:f, :g).with(1) assert_equal "[f(1), g(1)]", exp.to_s end def test_explicit_ordering_with_limits_allow_multiple_return_values FlexMock.use('mock') do |m| m.should_receive(:f).with(2).once.and_return { :first_time } m.should_receive(:f).with(2).twice.and_return { :second_or_third_time } m.should_receive(:f).with(2).and_return { :forever } assert_equal :first_time, m.f(2) assert_equal :second_or_third_time, m.f(2) assert_equal :second_or_third_time, m.f(2) assert_equal :forever, m.f(2) assert_equal :forever, m.f(2) assert_equal :forever, m.f(2) assert_equal :forever, m.f(2) assert_equal :forever, m.f(2) assert_equal :forever, m.f(2) assert_equal :forever, m.f(2) end end def test_global_methods_can_be_mocked m = flexmock("m") m.should_receive(:mock_top_level_function).and_return(:mock) assert_equal :mock, m.mock_top_level_function end def test_kernel_methods_can_be_mocked m = flexmock("m") m.should_receive(:mock_kernel_function).and_return(:mock) assert_equal :mock, m.mock_kernel_function end def test_undefing_kernel_methods_dont_effect_other_mocks m = flexmock("m") m2 = flexmock("m2") m.should_receive(:mock_kernel_function).and_return(:mock) assert_equal :mock, m.mock_kernel_function assert_equal :mkf, m2.mock_kernel_function end def test_expectations_can_by_marked_as_default m = flexmock("m") m.should_receive(:foo).and_return(:bar).by_default assert_equal :bar, m.foo end def test_default_expectations_are_search_in_the_proper_order m = flexmock("m") m.should_receive(:foo).with(Integer).once.and_return(:first).by_default m.should_receive(:foo).with(1).and_return(:second).by_default assert_equal :first, m.foo(1) assert_equal :second, m.foo(1) end def test_expectations_with_count_constraints_can_by_marked_as_default m = flexmock("m") m.should_receive(:foo).and_return(:bar).once.by_default assert_raises assertion_failed_error do flexmock_teardown end end def test_default_expectations_are_overridden_by_later_expectations m = flexmock("m") m.should_receive(:foo).and_return(:bar).once.by_default m.should_receive(:foo).and_return(:bar).twice m.foo m.foo end def test_default_expectations_can_be_changed_by_later_expectations m = flexmock("m") m.should_receive(:foo).with(1).and_return(:bar).once.by_default m.should_receive(:foo).with(2).and_return(:baz).once assert_raises check_failed_error do # This expectation should be hidded by the non-result m.foo(1) end m.foo(2) end def test_ordered_default_expectations_can_be_specified m = flexmock("m") m.should_receive(:foo).ordered.by_default m.should_receive(:bar).ordered.by_default m.bar assert_raises check_failed_error do m.foo end end def test_ordered_default_expectations_can_be_overridden m = flexmock("m") m.should_receive(:foo).ordered.by_default m.should_receive(:bar).ordered.by_default m.should_receive(:bar).ordered m.should_receive(:foo).ordered m.bar m.foo end def test_by_default_works_at_mock_level m = flexmock("m", :foo => :bar, :pooh => :bear, :who => :dey).by_default m.should_receive(:pooh => :winnie) assert_equal :bar, m.foo assert_equal :dey, m.who assert_equal :winnie, m.pooh end def test_by_default_at_mock_level_does_nothing_with_no_expectations flexmock("m").by_default end def test_partial_mocks_can_have_default_expectations obj = Object.new flexmock(obj).should_receive(:foo).and_return(:bar).by_default assert_equal :bar, obj.foo end def test_partial_mocks_can_have_default_expectations_overridden obj = Object.new flexmock(obj).should_receive(:foo).and_return(:bar).by_default flexmock(obj).should_receive(:foo).and_return(:baz) assert_equal :baz, obj.foo end def test_wicked_and_evil_tricks_with_by_default_are_thwarted mock = flexmock("mock") exp = mock.should_receive(:foo).and_return(:first).once mock.should_receive(:foo).and_return(:second) ex = assert_raises(FlexMock::UsageError) do exp.by_default end assert_match %r(previously defined), ex.message assert_equal :first, mock.foo assert_equal :second, mock.foo end def test_mocks_can_handle_multi_parameter_respond_tos mock = flexmock("a mock", :foo => :bar) assert mock.respond_to?(:foo) assert mock.respond_to?(:foo, true) assert mock.respond_to?(:foo, false) assert ! mock.respond_to?(:phoo) assert ! mock.respond_to?(:phoo, false) assert ! mock.respond_to?(:phoo, true) end def test_backtraces_point_to_should_receive_line mock = flexmock("a mock") file_name_re = Regexp.quote(__FILE__) line_no = __LINE__ + 1 mock.should_receive(:foo).and_return(:bar).once begin flexmock_verify rescue Exception => ex exception = ex end refute_nil exception assert_match(/#{file_name_re}:#{line_no}/, exception.backtrace.first) end def test_can_mock_operators assert_operator(:[]) { |m| m[1] } assert_operator(:[]=) { |m| m[1] = :value } assert_operator(:**) { |m| m ** :x } assert_operator(:+@) { |m| +m } assert_operator(:-@) { |m| -m } assert_operator(:+) { |m| m + :x } assert_operator(:-) { |m| m - :x } assert_operator(:*) { |m| m * :x } assert_operator(:"/") { |m| m / :x } assert_operator(:%) { |m| m % :x } assert_operator(:~) { |m| ~m } # ) assert_operator(:&) { |m| m & :x } assert_operator(:|) { |m| m | :x } assert_operator(:^) { |m| m ^ :x } assert_operator(:<) { |m| m < :x } assert_operator(:>) { |m| m > :x } assert_operator(:>=) { |m| m >= :x } assert_operator(:<=) { |m| m <= :x } assert_operator(:==) { |m| m == :x } assert_operator(:===) { |m| m === :x } assert_operator(:<<) { |m| m << :x } assert_operator(:>>) { |m| m >> :x } assert_operator(:<=>) { |m| m <=> :x } assert_operator(:=~) { |m| m =~ :x } assert_operator(:"`") { |m| m.`("command") } # ` end private def assert_operator(op, &block) m = flexmock("mock") m.should_receive(op).and_return(:value) assert_equal :value, block.call(m) end end class TestFlexMockShouldsWithInclude < Minitest::Test include FlexMock::ArgumentTypes def test_include_enables_unqualified_arg_type_references FlexMock.use("x") do |m| m.should_receive(:hi).with(any).once m.hi(1) end end end class TestFlexMockArgTypesDontLeak < Minitest::Test def test_unqualified_arg_type_references_are_undefined_by_default ex = assert_raises(NameError) do FlexMock.use("x") do |m| m.should_receive(:hi).with(any).once m.hi(1) end end assert_match(/\bany\b/, ex.message, "Error message should mention 'any'") end end flexmock-2.0.4/test/spys_test.rb000066400000000000000000000122721263476550700167110ustar00rootroot00000000000000#!/usr/bin/env ruby require 'test_helper' class TestSpys < Minitest::Test include FlexMock::Minitest class FooBar def foo :foofoo end def bar end end def setup super @spy = flexmock(:on, FooBar) end def test_spy_detects_simple_call @spy.foo assert_spy_called @spy, :foo end def test_spy_detects_simple_call_ignoring_args @spy.foo(1) assert_spy_called @spy, :foo, :_ end def test_spy_rejects_a_never_made_call @spy.foo assert_spy_not_called @spy, :bar end def test_spy_detects_call_with_literal_arg @spy.foo(1) assert_spy_called @spy, :foo, 1 end def test_spy_detects_call_with_class_arg @spy.foo(1) assert_spy_called @spy, :foo, Integer end def test_spy_rejects_call_with_non_matching_literal_arg @spy.foo(2) assert_spy_not_called @spy, :foo, 1 end def test_spy_detects_call_with_multiple_arguments @spy.foo(1, "HI", :foo) assert_spy_called @spy, :foo, /1/, "HI", Symbol end def test_spy_detects_multiple_calls_with_different_arguments @spy.foo(1) @spy.foo(1) assert_spy_called @spy, {:times => 2}, :foo, 1 end def test_spy_rejects_if_times_options_not_matching @spy.foo(1) @spy.foo(1) assert_spy_not_called @spy, {:times => 1}, :foo, 1 end def test_spy_detects_a_block @spy.foo { } assert_spy_called @spy, :foo, Proc end def test_spy_rejects_a_block @spy.foo { } assert_spy_not_called @spy, {:with_block => false}, :foo end def test_spy_detects_a_missing_block @spy.foo assert_spy_called @spy, {:with_block => false}, :foo end def test_spy_rejects_a_missing_block @spy.foo assert_spy_not_called @spy, :foo, Proc end def test_spy_ignores_block @spy.foo { } assert_spy_called @spy, :foo, Proc end def test_spy_accepts_correct_additional_validations @spy.foo(2) is_even = proc { |n| assert_equal 0, n%2 } assert_spy_called @spy, { :and => is_even }, :foo, Integer end def test_spy_accepts_multiple_additional_validations_first_failing @spy.foo(4) is_two = proc { |n| assert_equal 2, n } is_even = proc { |n| assert_equal 0, n%2 } assert_failed(/Expected: 2.*Actual: 4/mi) do assert_spy_called @spy, { :and => [is_two, is_even] }, :foo, Integer end end def test_spy_accepts_multiple_additional_validations_second_failing @spy.foo(4) is_even = proc { |n| assert_equal 0, n%2 } is_two = proc { |n| assert_equal 2, n } assert_failed(/Expected: 2.*Actual: 4/mi) do assert_spy_called @spy, { :and => [is_even, is_two] }, :foo, Integer end end def test_spy_rejects_incorrect_additional_validations @spy.foo(3) is_even = proc { |n| assert_equal 0, n%2 } assert_failed(/Expected: 0.*Actual: 1/mi) do assert_spy_called @spy, { :and => is_even }, :foo, Integer end end def test_spy_selectively_applies_additional_validations @spy.foo(2) @spy.foo(3) @spy.foo(4) is_even = proc { |n| assert_equal 0, n%2 } assert_failed(/Expected: 0.*Actual: 1/mi) do assert_spy_called @spy, { :and => is_even, :on => 2 }, :foo, Integer end end def assert_failed(message_pattern) failed = false begin yield rescue assertion_failed_error => ex failed = true assert_match message_pattern, ex.message end assert(failed, "Expected block to fail") end def test_spy_methods_can_be_stubbed @spy.should_receive(:foo).and_return(:hi) result = @spy.foo assert_equal result, :hi assert_spy_called @spy, :foo end def test_spy_cannot_see_normal_methods foo = FooBar.new flexmock(foo) assert_equal :foofoo, foo.foo assert_spy_not_called foo, :foo end def test_spy_cannot_see_normal_methods2 foo = FooBar.new flexmock(foo).should_receive(:foo).pass_thru assert_equal :foofoo, foo.foo assert_spy_called foo, :foo end def test_calling_non_spy_base_methods_is_an_error assert_raises(NoMethodError) do @spy.baz end end def test_cant_put_expectations_on_non_base_class_methodsx ex = assert_raises(NoMethodError) do @spy.should_receive(:baz).and_return(:bar) end assert_match(/cannot stub.*defined.*base.*class/i, ex.message) assert_match(/method: +baz/i, ex.message) assert_match(/base class: +TestSpys::FooBar/i, ex.message) end def test_cant_put_expectations_on_non_base_class_methods_unless_explicit @spy.should_receive(:baz).explicitly.and_return(:bar) @spy.baz assert_spy_called @spy, :baz end def test_ok_to_use_explicit_even_when_its_not_needed @spy.should_receive(:foo).explicitly.and_return(:bar) @spy.foo assert_spy_called @spy, :foo end def test_can_spy_on_partial_mocks @foo = FooBar.new @spy = flexmock(@foo) @foo.should_receive(:foo => :baz) result = @foo.foo assert_equal :baz, result assert_spy_called @foo, :foo end def test_can_spy_on_class_defined_methods flexmock(FooBar).should_receive(:new).and_return(:dummy) FooBar.new assert_spy_called FooBar, :new end def test_can_spy_on_regular_mocks mock = flexmock("regular mock") mock.should_receive(:foo => :bar) mock.foo assert_spy_called mock, :foo end end flexmock-2.0.4/test/symbol_extensions_test.rb000066400000000000000000000003761263476550700215010ustar00rootroot00000000000000require 'test_helper' class SymbolEtentensionsTest < Minitest::Test def test_as_name_converts_appropriatly method_name_class = self.class.instance_methods.first.class assert_equal method_name_class, :some_name.flexmock_as_name.class end end flexmock-2.0.4/test/test_class_extensions.rb000066400000000000000000000010641263476550700212740ustar00rootroot00000000000000require 'test_helper' class ClassExtensionsTest < Minitest::Test class Dog def wag end def method_missing(sym, *args, &block) if sym == :bark :woof else super end end def responds_to?(sym) sym == :bark || super end end def test_class_directly_defines_method assert Dog.flexmock_defined?(:wag) end def test_class_indirectly_defines_method assert ! Dog.flexmock_defined?(:bark) end def test_class_does_not_define_method assert ! Dog.flexmock_defined?(:jump) end end flexmock-2.0.4/test/test_helper.rb000066400000000000000000000053771263476550700172020ustar00rootroot00000000000000begin require 'simplecov' require 'coveralls' SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter ] SimpleCov.start do add_filter "/test/" end rescue LoadError end require 'minitest/autorun' require 'fileutils' require 'redirect_error' require 'flexmock' require 'flexmock/minitest_integration' class FlexMock module Minitest def assertion_failed_error FlexMock.framework_adapter.assertion_failed_error end def check_failed_error FlexMock.framework_adapter.check_failed_error end # Assertion helper used to assert validation failure. If a # message is given, then the error message should match the # expected error message. def assert_failure(klass, options={}, &block) message = options[:message] ex = assert_raises(klass) { yield } if message case message when Regexp assert_match message, ex.message when String assert ex.message.index(message), "Error message '#{ex.message}' should contain '#{message}'" end end ex end # Similar to assert_failure, but assumes that a mock generated # error object is return, so additional tests on the backtrace are # added. def assert_mock_failure(klass, options={}, &block) ex = assert_failure(klass, options, &block) file = eval("__FILE__", block.binding) assert_matching_line(ex, file, options) end # Assert that there is a line matching file in the backtrace. # Options are: # # deep: true -- matching line can be anywhere in backtrace, # otherwise it must be the first. # # line: n -- Add a line number to the match # def assert_matching_line(ex, file, options) line = options[:line] search_all = options[:deep] if line loc_re = /#{Regexp.quote(file)}:#{line}/ else loc_re = Regexp.compile(Regexp.quote(file)) end if search_all bts = ex.backtrace.join("\n") assert_with_block("expected a backtrace line to match #{loc_re}\nBACKTRACE:\n#{bts}") { ex.backtrace.any? { |bt| loc_re =~ bt } } else assert_match(loc_re, ex.backtrace.first, "BACKTRACE:\n #{ex.backtrace.join("\n ")}") end ex end def assert_with_block(msg=nil) unless yield assert(false, msg || "Expected block to yield true") end end def pending(msg="") state = "PASSING" begin yield rescue Exception => _ state = "FAILING" end where = caller.first.split(/:in/).first puts "\n#{state} PENDING TEST (#{msg}) #{where}" end end end flexmock-2.0.4/test/test_unit_integration/000077500000000000000000000000001263476550700207445ustar00rootroot00000000000000flexmock-2.0.4/test/test_unit_integration/auto_test_unit_test.rb000077500000000000000000000016671263476550700254130ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require "test_helper" require "flexmock/base" require "flexmock/test_unit" class TestFlexmockTestUnit < Test::Unit::TestCase def teardown failed = false begin super rescue Exception => ex failed = true end assert_equal @should_fail, failed, "Expected failed to be #{@should_fail}" end # This test should pass. def test_can_create_mocks m = flexmock("mock") m.should_receive(:hi).once m.hi @should_fail = false end # This test should fail during teardown. def test_should_fail__mocks_are_auto_verified m = flexmock("mock") m.should_receive(:hi).once @should_fail = true end end flexmock-2.0.4/test/test_unit_integration/minitest_teardown_test.rb000066400000000000000000000004711263476550700260710ustar00rootroot00000000000000require "minitest/autorun" require 'flexmock/test_unit' class SimpleTest < MiniTest::Unit::TestCase # This validates that the minitest teardown method is properly # aliased when using MiniTest. # # (see https://github.com/jimweirich/flexmock/issues/14). # def test_flexmock flexmock() end end flexmock-2.0.4/test/test_unit_integration/tu_integration_test.rb000066400000000000000000000046551263476550700253750ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require 'test_helper' # The following tests exercise Test::Unit integration. They are # disabled if actually running under MiniTest because the MiniTest is # different enough internally that the tests are not worthwhile. unless defined?(MiniTest) class TestTuIntegrationFlexMockMethod < Test::Unit::TestCase include FlexMock::Minitest def test_can_construct_flexmock mock = flexmock("x") mock.should_receive(:hi).and_return(:hello) assert_equal :hello, mock.hi end def test_can_construct_flexmock_with_block mock = flexmock("x") do |m| m.should_receive(:hi).and_return(:hello) end assert_equal :hello, mock.hi end end class TestTuIntegrationMockVerificationInTeardown < Test::Unit::TestCase include FlexMock::Minitest def teardown assert_raise(assertion_failed_error) do super end end def test_mock_verification_occurs_during_teardown flexmock("xyz").should_receive(:hi).with(any).once end end class TestTuIntegrationMockVerificationWithoutSetup < Test::Unit::TestCase include FlexMock::Minitest def teardown assert_raise(assertion_failed_error) do super end end def test_mock_verification_occurs_during_teardown flexmock("xyz").should_receive(:hi).with(any).once end end class TestTuIntegrationMockVerificationForgetfulSetup < Test::Unit::TestCase include FlexMock::Minitest def teardown assert_raise(assertion_failed_error) do super end end def test_mock_verification_occurs_during_teardown flexmock("xyz").should_receive(:hi).with(any).once end end class TestTuIntegrationSetupOverridenAndNoMocksOk < Test::Unit::TestCase include FlexMock::Minitest def test_mock_verification_occurs_during_teardown end end class TestTuIntegrationFailurePreventsVerification < Test::Unit::TestCase include FlexMock::Minitest def test_mock_verification_occurs_during_teardown flexmock('m').should_receive(:hi).once simulate_failure end private def simulate_failure @test_passed = false end end end flexmock-2.0.4/test/undefined_test.rb000066400000000000000000000040431263476550700176510ustar00rootroot00000000000000#!/usr/bin/env ruby #--- # Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com). # All rights reserved. # Permission is granted for use, copying, modification, distribution, # and distribution of modified versions of this work as long as the # above copyright notice is included. #+++ require "test_helper" class UndefinedTest < Minitest::Test def test_undefined_method_calls_return_undefined assert_undefined undefined.some_random_undefined_method end def test_equals assert undefined == undefined assert ! (undefined == Object.new) end def test_math_operators assert_undefined undefined + 1 assert_undefined undefined - 1 assert_undefined undefined * 1 assert_undefined undefined / 1 assert_undefined undefined ** 1 end def test_math_operators_reversed assert_undefined 1 + undefined assert_undefined 1 - undefined assert_undefined 1 * undefined assert_undefined 1 / undefined assert_undefined 2 ** undefined end def test_comparisons assert_undefined undefined < 1 assert_undefined undefined <= 1 assert_undefined undefined > 1 assert_undefined undefined >= 1 assert_undefined undefined <=> 1 end def test_comparisons_reversed assert_undefined 1 < undefined assert_undefined 1 <= undefined assert_undefined 1 > undefined assert_undefined 1 >= undefined assert_undefined 1 <=> undefined end def test_base_level_methods assert_kind_of FlexMock::Undefined, undefined end def test_cant_create_a_new_undefined assert_raises(NoMethodError) do FlexMock::Undefined.new end end def test_cant_clone_undefined assert_undefined undefined.clone assert_equal undefined.__id__, undefined.clone.__id__ end def test_string_representations assert_equal "-UNDEFINED-", undefined.to_s assert_equal "-UNDEFINED-", undefined.inspect end def test_undefined_is_not_nil assert ! undefined.nil? end private def assert_undefined(obj) assert undefined == obj end def undefined FlexMock.undefined end end flexmock-2.0.4/todo.txt000066400000000000000000000007761263476550700150640ustar00rootroot00000000000000Short term things to do: * Explicit => Explicitly DONE * Consolidate mock argument matching and spy argument matching * Consolidate mock block detection and spy block detection. * Consolidate the :on option with mocks * Pass through mode for partial mocks * Update readme * auto-mock class when using base_class IDEAS spy.should have_received(:foo).with(arg1, arg2) # PREFERRED spy.should have_received.foo(arg1, arg2) assert_called spy, :foo, arg1, arg2 assert_spy(spy).received(:foo).with(arg1, arg2)