官术网_书友最值得收藏!

  • RSpec Essentials
  • Mani Tadayon
  • 398字
  • 2021-07-09 19:33:38

Structure of a spec file

Let's look again at the AddressValidator module we introduced in Chapter 1, Exploring Testability from Unit Tests to Behavior-Driven Development, so we can understand its structure better. We'll also use some basic RSpec features to improve the tests. Let's look at the spec code:

require 'rspec'
require_relative 'address_validator'

describe AddressValidator do
  it "returns false for incomplete address" do
    address = { street: "123 Any Street", city: "Anytown" }
    expect(
      AddressValidator.valid?(address)
    ).to eq(false)
  end

  it "missing_parts returns an array of missing required parts" do
    address = { street: "123 Any Street", city: "Anytown" }
    expect(
      AddressValidator.missing_parts(address)
    ).to eq([:region, :postal_code, :country])
  end
end

We defined a local variable address in each example. This is fine for simple, one-off values. We could get the same functionality shared across multiple tests with a local function defined within the scope:

describe AddressValidator do
  def address
    { street: "123 Any Street", city: "Anytown" }
  end

  it "returns false for incomplete address" do
    expect(AddressValidator.valid?(address)).to eq(false)
  end

  it "missing_parts returns an array of missing required parts" do
    expect(
      AddressValidator.missing_parts(address)
    ).to eq([:region, :postal_code, :country])
  end
end

If the same value is used in more than one test, an instance variable in a before block can be used:

describe AddressValidator do

  # this block replaces the 'address' method
  before do
    @address = { street: "123 Any Street", city: "Anytown" }
  end

  it "valid? returns false for incomplete address" do
    expect(
      AddressValidator.valid?(@address)
    ).to eq(false)
  end

  it "missing_parts returns an array of missing required parts" do
    expect(
      AddressValidator.missing_parts(@address)
    ).to eq([:region, :postal_code, :country])
  end
end

In many cases, the object needs to change slightly from one test case to another. Local variables, local functions, or instance variables are tedious and make it hard to see the differences between test cases. For example, if we wanted to test for invalid characters in a city name, we would have the following:

describe AddressValidator do
  before do
    @address = { street: "123 Any Street", city: "Anytown" }
  end

  it "valid? returns false for incomplete address" do
    expect(AddressValidator.valid?(@address)).to eq(false)
  end

  it "missing_parts returns an array of missing required parts" do
    expect(
      AddressValidator.missing_parts(@address)
    ).to eq([:region, :postal_code, :country])
  end

  context "invalid characters in value" do
    before do
      # notice the value for :city includes special characters
      @address = { street: "123 Any Street", city: "Any$town%" }
    end

    it "invalid_parts returns keys with invalid values" do
      expect(
        AddressValidator.invalid_parts(@address)
      ).to eq([:city])
    end
  end
end
主站蜘蛛池模板: 海安县| 石柱| 广州市| 双牌县| 息烽县| 垣曲县| 宁阳县| 绿春县| 金堂县| 资源县| 阿瓦提县| 红原县| 青神县| 凭祥市| 大悟县| 桐城市| 宣武区| 盐池县| 曲靖市| 鹤壁市| 浙江省| 香港 | 临安市| 韩城市| 金门县| 定州市| 饶平县| 怀来县| 余江县| 古丈县| 马龙县| 嘉兴市| 雅安市| 荃湾区| 肇州县| 淮北市| 越西县| 中超| 柳林县| 思茅市| 武山县|