def stub object, stub, visibility = nil, &proc
      [Symbol, String, Hash].include?(stub.class) ||
        raise(ArgumentError, 'a Symbol, String or Hash expected')

      if stub.is_a?(Hash)
        return hash_stub(object, stub, visibility, &proc)
      elsif stub =~ /\./
        return chained_stub(object, stub, visibility, &proc)
      end

      visibility ||= MiniSpec::Utils.method_visibility(object, stub) || :public
      stubs = (@__ms__stubs[object.__id__] ||= {})
      stubs[stub] ||= MiniSpec::Mocks::Stub.new(object, @__ms__messages, @__ms__stubs__originals)
      stubs[stub].stubify(stub, visibility, &proc)
      stubs[stub]
    end
def stub object, stub, visibility = nil, &proc
      [Symbol, String, Hash].include?(stub.class) ||
        raise(ArgumentError, 'a Symbol, String or Hash expected')

      if stub.is_a?(Hash)
        return hash_stub(object, stub, visibility, &proc)
      elsif stub =~ /\./
        return chained_stub(object, stub, visibility, &proc)
      end

      visibility ||= MiniSpec::Utils.method_visibility(object, stub) || :public
      stubs = (@__ms__stubs[object.__id__] ||= {})
      stubs[stub] ||= MiniSpec::Mocks::Stub.new(object, @__ms__messages, @__ms__stubs__originals)
      stubs[stub].stubify(stub, visibility, &proc)
      stubs[stub]
    end
stubbing given method and keeps original visibility

 if a block given, it will receive original method as first argument
 and any passed parameters as rest arguments.

 @example make Some::Remote::API.call to return success
   stub(Some::Remote::API, :call) { :success }

 @example call original
   stub(obj, :a) {|orig| orig.call}

 @param object object to define stub on
 @param stub  method to be stubbed.
     if a Hash given, keys will be stubbed methods and values return values
 @param [Proc] &proc  block to be yielded when stub called
 @return MiniSpec::Mocks::Stub instance