Day19 - 汇入 excel-测试篇

前言

上篇汇入 Excel 实作,这篇以撰写测试为主

实作

测试的写法有蛮多种,这边以其中一种为例,可参考此 pr

# spec/services/shops_excel/parser_spec.rb

require 'rails_helper'

RSpec.describe ShopsExcel::Parser do
  describe 'execute' do
    let(:excel_file) { Tempfile.new(%w[shops_import .xlsx]) }
    let(:excel) do
      file = excel_file
      file.binmode

      xlsx = Axlsx::Package.new
      workbook = xlsx.workbook
      workbook.add_worksheet(name: '商家清单') do |sheet|
        sheet.add_row(excel_titles)
        sheet.add_row(content_array1)
        sheet.add_row(content_array2)
      end
      xlsx.use_shared_strings = true
      xlsx.serialize(file)

      file.rewind
      file
    end
    let(:excel_titles) { ShopsExcel::Generator::TITLES }
    let(:content_array1) { ['shop_name_1', '[email protected]', 'hello'] }
    let(:content_array2) { ['shop_name_2', '[email protected]',  'world'] }

    subject { described_class.new.execute(excel) }

    context 'create shops successfully' do
      it 'data correctly' do
        expect { subject }.to change { Shop.count }.by(2)
        [content_array1, content_array2].each do |content_array|
          shop1 = Shop.find_by(name: content_array[0])
          expect(shop1).to have_attributes(
            name: content_array[0],
            email: content_array[1],
            note: content_array[2],
          )
        end
      end
    end

    context 'when return error' do
      let(:logger) { double }

      before do
        allow(Rails).to receive(:logger).and_return(logger)
      end

      def expect_error_message(error_message)
        expect(logger).to receive(:error).with(/\[ShopsExcel::Parser Error\] #{error_message}/)
        expect { subject }.to change { Shop.count }.by(0)
      end

      context 'when title is empty' do
        let(:excel_titles) { [nil, nil, nil] }
        let(:error_message) { '输入资料有误,比对 Excel 标头与预期不同' }

        it { expect_error_message(error_message) }
      end

      context 'when data is empty' do
        let(:content_array1) { [nil, nil, nil] }
        let(:content_array2) { content_array1 }
        let(:error_message) { '无资料' }

        it { expect_error_message(error_message) }
      end

      context 'when data is duplicate' do
        let(:content_array2) { content_array1 }
        let(:error_message) { '有重复的商家名称,请检查' }

        it { expect_error_message(error_message) }
      end

      context 'when shop exists' do
        let(:shop) { create(:shop) }
        let(:content_array1) { [shop.name, shop.email, shop.note] }
        let(:content_array2) { ['shop_name_2', '[email protected]', 'world'] }
        let(:error_message) { "有 1 笔已建立过: #{shop.name}" }

        it { expect_error_message(error_message) }
      end
    end
  end
end

小结

这篇其实是与上篇一起先写好 code ,接着才开始写文章,在写测试过程中,有发现原本写的方法要微调,这也是撰写测试的好处,能发现一些没留意到的眉眉角角 (说这麽多,就是挤牙膏嘛)

若有更好的写法,欢迎留言和我说~

参考资料

  1. Roo GitHub

铁人赛文章连结:https://ithelp.ithome.com.tw/articles/10272599
medium 文章连结:https://link.medium.com/sYWyCHbyRjb
本文同步发布於 小菜的 Blog https://riverye.com/

备注:之後文章修改更新,以个人部落格为主


<<:  抓取资料库数据 - SQL基础语法(中)

>>:  JavaScript入门 Day27_while回圈

AI ninja project [day 13] 回归

这应该也是学习深度学习时的基础课程, 不确定跟图像分类比,哪一个会先学到, 但是在接触深度学习框架时...

[Day 33] 自我介绍後台及前台(二) - 图片上传

自我介绍资料验证 我们昨天完成了自我介绍的画面部分, 那今天就开始做资料的验证, 我们用以下的方式做...

风险的决策应在投资评估过程中行使

-什麽是风险? 选项B提供了最佳视角,但正确的版本应为“剩余风险低於董事会的风险承受能力。” 基於...

[D03] 取样与量化(1)

我们在用电脑处理影像时,由於电脑只看得懂数字,所以影像必须要以离散(discrete)的形式处理,也...

DAY07 - API架构分享

其实大家可能都有自己的API架构方式,不过我这边就是分享我目前在Web端撰写API时,在架构上和开发...