#We can't do a lot here because the interface seems bad -- this test being gnarly is not rspec's fault. require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "Something doppelganger" do #does login/password matter? Why are we setting them to random values instead of using Factory.build? let(:railcar) { RailCar.new(:login => "a", :password => "b") context "when it is rejected" do #Do these values in the parse response matter? It seems like they don't if we're testing only non-nil #If they don't matter, let's not set them let(:parse_response) do { :requestID => "123", :vehicleCodeRaw => "N9", :requestToken => "AFLAKJFLDKJFSLDKFJSLDFKJn129399NANF)(A)FNnnnfnfnnfnf", :amount => "90.01" } end #Are we sending because these methods are private? If so we shouldn't be exercising them in this test. let(:response) { railcar.send(:commit, request, {}) } subject { response } before do #railcar should not be stubbed if it is unit tested railcar.stub(:parse).and_return(parse_response) railcar.send(:build_request, 9011, "token", {}) end #it would be nice if we had an expected name here, not nil is not useful. # It would also be nice if this returned a real object instead of a hash if there are multiple values # If there *are* multiple values, why are we only testing name? If there aren't, why do we have a hash # just for name? its(:name) { should_not be_nil } end end #This test isn't going to exhibit the true flexibility of let/it/subject because # 1) it only tests a single context, # and 2) it only makes one assertion. # its/let/subject when used correctly does a few things: # 1) Keeps your tests strictly single assertion unit tests. # 2) No lies in it strings because you don't write them # 3) More concise, less duplication of setup. # 4) If used correctly, makes it really obvious what inputs are varying that you care about