第 5 章 控制器测试

5.1基础

rails generate rspec:controller home

RSpec.describe HomeController, type: :controller do
  describe '#index' do
    it "responds successfully" do
      get :index
      expect(response).to be_success
      # response 对象包含应用返回给浏览器的所有数据,包括 HTTP 响应码。

# be_success 检查响应的状态是成 功(200 响应)还是失败(例如 500 异常)。

expect(response).to have_http_status "200"

    end
  end
end

be_success匹配器 ,have_http_status()匹配器

5.2要验证身份的controller test

如果程序有Devise。测试的时候,需要身份验证,则使用Devise Test helpers

Devise includes some test helpers for controller and integration tests. In order to use them, you need to include the repective module in you test cases/specs.

包含一个测试模块.

class PostsControllerTest < ActionController::TestCase
include Devise::Test::ControllerHelpers
end
class PostsTests < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
end
RSpec.configure do |config|
config.include Devise::Test::IntegrationHelpers, type: :feature
 config.include Devise::Test::ControllerHelpers, type: :controller
 config.include Devise::Test::ControllerHelpers, type: :view
end

然后就可以使用sign_in, sign_out方法了

redirect_to 匹配器

以下测试都是get的测试。

ProjectsController
  #inde
    as an authenticated user
      responds successfully
      returns a 200 response
    as a guest
      returns a 302 response

redirects to the sign_in page

  #show
    as an authorized user
      responds successfully
    as an unauthorized user
      redirects to the dashboard

5.3 测试用户输入。

HTTP GET外,还有POST, PATCH, DELETE与controller交互。

Method: FactoryBot::Syntax::Methods#attributes_for

#attributes_for(name, *traits_and_overrides, &block) ⇒ Hash

根据factories中的注册的name, 生成一个hash属性。

  describe '#create' do
    context "as an authenticated user" do
      before do
        @user = FactoryGirl.create(:user)
      end
      it "adds a project" do
        project_params = FactoryGirl.attributes_for(:project)
        sign_in @user
        expect {
          post :create, params: {project: project_params }
        }.to change(@user.projects, :count).by(1)

#expect(@user.projects.count).to eq(1)  #替代方法

      end
    end

change()方法,by()方法,是哪里定义的?

在gem rspec-expectations 中定义的。

This class is part of a private API. 文档提示:私有类,尽量避免使用.

https://www.rubydoc.info/gems/rspec-expectations/RSpec/Matchers:change

  describe '#update' do
    context 'as an authorized user' do
      before do
        @user = FactoryGirl.create(:user)
        @project = FactoryGirl.create(:project, owner: @user)
      end
      it "updates a project" do
        project_params = FactoryGirl.attributes_for(:project, name: "New Project Name")
        sign_in @user
        patch :update, params: {id: @project.id, project: project_params}

#已经更新数据库,但内存里@project实例变量没有更新,所以要reload.

        @project.reload
        expect(@project.name).to eq "New Project Name"
      end
    end
  end

reload()方法 从数据库中根据接收者的primary-key id调取record并更新接收者的属性。

Reloading is commonly used in test suites to test something is actually written to the database, or when some action modifies the corresponding row in the database but not the object in memory:

经常用于测试,测试记录实际已写入数据库,或者测试当一些action在数据库中修改了相关记录但在内存中已存在这个对象变量是否更新。

5.4 测试用户输入导致的错误

    context "with invalid attributes" do
      before do
        @user = FactoryGirl.create(:user)
      end
      it "does not add a project" do
        project_params = FactoryGirl.attributes_for(:project, :invalid)
        sign_in @user
        post :create, params: {project: project_params}
        expect(@user.projects.count).to eq(0)
        # expect {
        #   post :create, params: { project: project_params }
        # }.to_not change(@user.projects, :count)
      end
    end

这里用到trait,在projects.rb的中定义的一个trait

trait :invalid do

name nil

end

⚠️ trait 和 factory继承的区别,一个是增加特点,用的时候需要和预构件一起用;一个是完全继承父类属性并增加自己的特色,是一个新的预构件。

5.5

处理非 HTML 输出 ,如何编写对JSON格式的测试。

bin/rails g rspec:controller
tasks

spec/controllers/tasks_controller_spec.rb 测试控制器show动作

RSpec.describe TasksController, type: :controller do
  before do
    @user = FactoryGirl.create(:user)
    @project = FactoryGirl.create(:project, owner:@user)
    @task = @project.tasks.create!(name: "Test task")
  end
  describe '#show' do
    it "responds with JSON formatted output" do
      sign_in @user
      get :show, format: :json,
        params:{project_id: @project.id, id: @task.id}
      expect(response.content_type).to eq "application/json"
    end
  end
end
通过format: :json格式,控制器处理相应的请求,返回application/json类型的内容。

content_type方法属于 ActionDispatch::Response类的实例方法。

5.6小结

控制器测试,测试的是user登陆和未登陆状态下,已经不同用户权限下,对action 是否成功的测试。

在实际测试中,控制器测试已经不流行了。

Rspec: everyday-rspec实操。5:controller test(了解基础)的更多相关文章

  1. Rspec: everyday-rspec实操。FactoryBot预构件 (rspec-expectations gem 查看匹配器) 1-4章

    总文档连接: RSpec.info/documentation/ 包括core, expectiation,rails , mock, 点击最新版本,然后右上角搜索class, method. 第3章 ...

  2. Istio的流量管理(实操二)(istio 系列四)

    Istio的流量管理(实操二)(istio 系列四) 涵盖官方文档Traffic Management章节中的inrgess部分. 目录 Istio的流量管理(实操二)(istio 系列四) Ingr ...

  3. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  4. 号外号外:9月13号《Speed-BI云平台案例实操--十分钟做报表》开讲了

    引言:如何快速分析纷繁复杂的数据?如何快速做出老板满意的报表?如何快速将Speed-BI云平台运用到实际场景中?         本课程将通过各行各业案例背景,将Speed-BI云平台运用到实际场景中 ...

  5. Mysql MHA(GTID)配置(实操)

    实现环境 centos6.7 MYSQL5.6.36 主:192.168.1.191 从1:192.168.1.145 从2:192.168.1.146 监测:放在从2上 192.168.1.146 ...

  6. Selenium之unittest测试框架详谈及实操

    申明:本文是基于python3.x及selenium3.x. unittest,也可以称为PyUnit,可以用来创建全面的测试套件,可以用于单元自动化测试(模块).功能自动化测试(UI)等等. 官方文 ...

  7. unittest测试框架详谈及实操(二)

    类级别的setUp()方法与tearDown()方法 在实操(一)的例子中,通过setUp()方法为每个测试方法都创建了一个Chrome实例,并且在每个测试方法执行结束后要关闭实例.是不是觉得有个多余 ...

  8. .net基础学java系列(四)Console实操

    上一篇文章 .net基础学java系列(三)徘徊反思 本章节没啥营养,请绕路! 看视频,不实操,对于上了年龄的人来说,是记不住的!我已经看了几遍IDEA的教学视频: https://edu.51cto ...

  9. RTN 实操

    创建房间 test-rtn 10001 e2uii6r7r 8LfwOcreM76OiV1V1y8jXrMG_BNa-cmktpWUznRa:kdYdsEpcYLc5ceWEHPaK0ZDI7Qc=: ...

  10. 6.3 Pandora 实操 - 数据立方

    简介 数据立方是适用于大规模实时数据(每天百亿条,10TB+ 级别数据)查询与分析的数据库系统,提供交互式的访问数据的能力,支持数据过滤.分组.聚合,实现亚秒级以内对亿行级别的数据表进行多维探索分析. ...

随机推荐

  1. vue 渲染页面的时候 出现闪烁问题的解决办法

    在使用vue绑定数据的时候,渲染页面时会出现变量闪烁 <div id="h_cameraman" v-cloak> <public-nav> {{ msg ...

  2. Python: 正则表达式匹配反斜杠 "\"

    Python正则表达式匹配反斜杠 "\" eg: >>>a='w\w\w' 'w\\w\\w' #  打印出来的 "\\" 被转义成 一个反斜 ...

  3. linux常用命令:chkconfig 命令

    chkconfig命令用来安装,查看或修改 services随系统启动的启动选项的设置.是Red Hat公司遵循GPL规则所开发的程序,它可查询操作系统在每一个执行等级中会执行哪些系统服务,其中包括各 ...

  4. js 技巧(智能社教程温故)

    1.js 中  NaN === NaN  值为false; 2.parseInt("abc") === NaN;(不是数字) 3.tab 纯js 实现.可以给当前循环的元素添加.i ...

  5. https的设置

    现有如下的web架构(简化之后的),需要把原来的http访问修改到https访问! haproxy的认证有两种方式: 第一种:haproxy提供ssl证书,后面的nginx访问使用正常的http. 第 ...

  6. P4001 [BJOI2006]狼抓兔子(对偶图)

    P4001 [BJOI2006]狼抓兔子 最短路+对偶图 看这题最容易想到的就是网络流.Dinic可以过,据说还跑得比正解快. 如果不写网络流,那么需要知道2个前置知识:平面图和对偶图(右转baidu ...

  7. 基于Android的闹钟的软件

    一.本课题要求:设计一个基于Android的闹钟的软件. 实现的功能有:能通过界面设置闹钟的启动条件建立后台服务进程,当满足触发条件时,闹钟响应相应事件. 二.需求分析 该课题实现在手机操作系统And ...

  8. 加强树状数组luogu3368

    暴力树状数组30分,这该怎么办: 知识点回顾 差分数组中 开头结尾改变了值之后 求他的前缀,发现区间内所有数都改变 然后我们做差分树状数组 #include<cstdio> using n ...

  9. P4013 数字梯形问题 网络流二十四题

    P4013 数字梯形问题 题目描述 给定一个由 nn 行数字组成的数字梯形如下图所示. 梯形的第一行有 m 个数字.从梯形的顶部的 m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形 ...

  10. 以太坊(Ethereum) - 节点时间未同步和区块同步失败案例分析

    背景 以太坊技术搭建的区块链网络,节点间需要保证时间一致,才能正常有序的发送交易和生成区块,使得众多节点共同维护分布式账本(区块数据+状态数据).但是,网络中节点的系统时间不一致回出现什么现象呢,我们 ...