Background:-
I'm currently writing a functional test for a particular controller's action in order to validate its functionality by making a POST request.
Background on controller's action -
This action is responsible for creating an application and saving it.
Controller's action code -
def create_applicaiton
application_data = {
application_name: request.POST['app_name']
member_email: request.POST['email']
}
application = ApplicationRecord.new application_data
begin
StepinHelper.create_issue(application) //Problem is with this
rescue => error
Rails.logger.error "Error occurred while creating Issue. Error: #{error}"
return render plain: "Error occurred while creating Issue. Please try later. Error: #{error}, status: internal_Server_error
end
begin
ActiveRecord::Base.transaction do
application.save!
end
rescue => error
Rails.logger.error "Error occurred while creating application. Error: #{error}"
return render plain: "Error occurred while creating application. Please try later. Error: #{error}, status: internal_Server_error
end
return head :ok
end
The problem is with the line -
StepinHelper.create_issue(application)
where create_issue method instantiates a class IssueCreator which makes some network calls in order to create the Issue (Think of issue as a notifier that indicates an application is created) which fails during the POST request as its a functional test and the scope is beyond that where it cannot make network calls.
Here is the code for create_issue method present in StepinHelper class -
module StepinHelper
def self.create_issue application
issue_title = application.application_name
issue = IssueCreator.new issue_title //instantiates IssueCreator class
issue_create = issue.create //This method creates the issue
issue_id = issue_create["id"] //This fetches the "issue_id" from the created issue
application.add_issue_id issue_id //This adds issue_id to the schema/table of ApplicationRecord
end
end
The model of the ApplicationRecord has a method - add_issue_id as mentioned above which adds a the value of issue_id to its schema's issue_id column.
This is the model of ApplicationRecord -
class ApplicationRecord < ActiveRecord::Base
self.table_name = "application_record"
......
......
def add_issue_id id
self.issue_id = id
end
....
....
This is the schema of ApplicationRecord where issue_id is set to be NOT NULL
create_table "application_record", id: integer
t.string "application_name", null: false
t.string "member_email", null:false
t.string "issue_id", null:false
end
This is my Functional test code I'm implementing using minitest -
class ApplicationControllerTest < ActionController::TestCase
test 'testing_create_applcication' do
StepinHelper.expects(:create_issue).once //mocking
post :create_application, params: {application_name: 'dummyName', member_email: '[email protected]'}
assert_response :ok
end
end
Main Problem:-
Trying to mock create_issue method like above. But my assertion fails with a 500 response because as I'm mocking create_issue method issue_id is not being created and stored in the application records.
Here is the error response -
Expected response to be a <200:ok> , but was a <500: Internal Server Error>
Response body: Error occurred while creating application. Error: SQLite3::ConstraintException: NOT NULL constraint failed: application_record.issue_id
Expected: 200
Actual: 500
Expectation/what I'm looking for: -
- To make sure issue_id is created by mocking the necessary methods
- To make my test case pass with a 200 response.
NOTE: I shouldn't make changes to the source code.