RSpec测试JSON API遇Webpacker文件缺失错误,求解决方案
问题:RSpec测试JSON API时出现Webpacker文件找不到错误
背景
我创建了一个工时表(timesheet),想用JSON API测试其CRUD功能,但运行RSpec测试时,控制台返回Webpacker无法找到文件的错误。
测试代码(创建工时表的RSpec代码)
it 'Create timesheet' do timesheet = { start_date: Date.new(2023,1,1), end_date: Date.new(2023,1,31) } sign_in_as_a_valid_user post "/timesheets.json", headers: headers, params: timesheet, as: :json expect(response).to have_http_status(:created) json_response = JSON.parse(response.body) byebug expect(json_response['start_date']).to eq(2023,1,1) expect(json_response['end_date']).to eq(2023,1,31) end
错误信息
运行测试后控制台返回的错误:
1) Api Create timesheet Failure/Error: <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload', defer: true %> ActionView::Template::Error: Webpacker can't find application.js in /home/yir/Documents/workspace/projet1/alpha/public/packs-test/manifest.json. Possible causes: 1. You want to set webpacker.yml value of compile to true for your environment unless you are using the `webpack -w` or the webpack-dev-server. 2. webpack has not yet re-run to reflect updates. 3. You have misconfigured Webpacker's config/webpacker.yml file. 4. Your webpack configuration is not creating a manifest. Your manifest contains: { }
补充(2023年4月18日):工时表控制器代码
class TimesheetsController < ApplicationController before_action :set_timesheet, only: %i[ show edit update destroy ] before_action :authenticate_user! # GET /timesheets or /timesheets.json def index @timesheets = Timesheet.order(start_date: :asc) end # GET /timesheets/1 or /timesheets/1.json def show end # GET /timesheets/new def new @timesheet = Timesheet.new my_date = Date.today @days = my_date.beginning_of_month.upto(my_date.end_of_month) end # GET /timesheets/1/edit def edit end # POST /timesheets or /timesheets.json def create @timesheet = Timesheet.new(timesheet_params) respond_to do |format| if @timesheet.save format.html { redirect_to @timesheet, notice: "Timesheet was successfully created." } format.json { render :show, status: :created, location: @timesheet } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @timesheet.errors, status: :unprocessable_entity } end end end # PATCH/PUT /timesheets/1 or /timesheets/1.json def update respond_to do |format| if @timesheet.update(timesheet_params) format.html { redirect_to @timesheet, notice: "Timesheet was successfully updated." } format.json { render :show, status: :ok, location: @timesheet } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @timesheet.errors, status: :unprocessable_entity } end end end # DELETE /timesheets/1 or /timesheets/1.json def destroy @timesheet.destroy respond_to do |format| format.html { redirect_to timesheets_url, notice: "Timesheet was successfully destroyed." } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_timesheet @timesheet = Timesheet.find(params[:id]) end # Only allow a list of trusted parameters through. def timesheet_params params.require(:timesheet).permit(:month, :start_date, :end_date) end end
解决方案
1. 配置测试环境自动编译Webpack资源
打开config/webpacker.yml,找到test环境配置,将compile设置为true:
test: <<: *default compile: true # 其他配置保持不变
这样测试时Webpack会自动编译缺失的资源,无需手动运行编译命令。
2. 手动编译测试环境的Webpack资源
在项目根目录执行以下命令,提前编译测试环境的前端资源:
RAILS_ENV=test bundle exec rails webpacker:compile
执行完成后再重新运行RSpec测试。
3. 修复测试参数并避免渲染HTML模板
从错误信息看,测试过程中触发了HTML模板渲染,核心原因有两个:
- 测试参数未按控制器要求包裹在
:timesheet键下,导致参数校验失败,控制器走了format.html分支渲染模板。修改测试参数为:
timesheet = { timesheet: { start_date: Date.new(2023,1,1), end_date: Date.new(2023,1,31) } }
- 检查
sign_in_as_a_valid_user方法,确保它仅设置认证会话(比如直接赋值session[:user_id] = valid_user.id),而非渲染HTML页面或跳转。
4. 简化测试环境的布局配置(可选)
如果API测试完全不需要前端资源,可以修改控制器,在测试环境下关闭API动作的布局:
class TimesheetsController < ApplicationController # ...其他代码 layout false, only: [:create, :update, :destroy, :index, :show] if Rails.env.test? # ...其他代码 end
这样测试时API动作不会渲染包含Webpack标签的布局。
内容的提问来源于stack exchange,提问作者yir
相关产品推荐
相关产品推荐

