Reputation: 5615
I have a Directory controller and a Files controller. I'm testing the Files controller. I've created valid attributes for the File and I'm trying to mock_model the Directory to get the test to pass. The GET tests all work, but none of the POST tests work. The POST tests all give the error: "Directory expected, got String."
describe FilesController do
def valid_attributes {
:name => "test",
:reference_id => 1,
:location => "/path/to/directory",
:software => "excel",
:software_version => "2010",
:directory => mock_model(Directory)
}
end
describe "POST create" do
describe "with valid params" do
it "creates a new AssemblyFile" do
expect {
post :create, :assembly_file => valid_attributes
}.to change(AssemblyFile, :count).by(1)
end
it "assigns a newly created assembly_file as @assembly_file" do
post :create, :assembly_file => valid_attributes
assigns(:assembly_file).should be_a(AssemblyFile)
assigns(:assembly_file).should be_persisted
end
it "redirects to the created assembly_file" do
post :create, :assembly_file => valid_attributes
response.should redirect_to(AssemblyFile.last)
end
end
end
1) FilesController POST create with valid params creates a new File
Failure/Error: post :create, :file => valid_attributes
ActiveRecord::AssociationTypeMismatch:
Directory(#87017560) expected, got String(#49965220)
# ./app/controllers/files_controller.rb:60:in `new'
# ./app/controllers/files_controller.rb:60:in `create'
# ./spec/controllers/files_controller_spec.rb:79:in `block (5 levels) in <top (required)>'
# ./spec/controllers/files_controller_spec.rb:78:in `block (4 levels) in <top (required)>'
If I look at the test.log file, it shows that assembly is a string ("assembly" => "1011"). So I'm not sure why the mock_model isn't creating an object?
I've tried using stub! instead of mock_model, but that gets complicated because the create! used for stub! needs a lot of its own valid variables set and I don't really want to have to set a whole bunch of other valid attributes for that when I'm not trying to even test the Directory controller at all.
What am I doing wrong in my approach here?
Upvotes: 0
Views: 1317
Reputation: 47548
Pass the id of the mock in the params hash instead of the mock itself. You'll also need to stub the find method so the mock is available in the controller action:
@directory = mock_model(Directory)
Directory.stub(:find).with(@directory.id).and_return(@directory)
post :create, :assembly_file => valid_attributes.merge(:directory_id => @directory.id)
# in controller
@directory = Directory.find(params[:assembly_file][:directory_id]) # => returns the mock
Upvotes: 1