diff --git a/Library/Homebrew/test/patching_spec.rb b/Library/Homebrew/test/patching_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dd849ca9235e5c450b67bd88e357ba142e86820a
--- /dev/null
+++ b/Library/Homebrew/test/patching_spec.rb
@@ -0,0 +1,289 @@
+require "formula"
+
+describe "patching" do
+  TESTBALL_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz".freeze
+  TESTBALL_PATCHES_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1-patches.tgz".freeze
+  PATCH_URL_A = "file://#{TEST_FIXTURE_DIR}/patches/noop-a.diff".freeze
+  PATCH_URL_B = "file://#{TEST_FIXTURE_DIR}/patches/noop-b.diff".freeze
+  PATCH_A_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-a.diff"
+  PATCH_B_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-b.diff"
+  APPLY_A = "noop-a.diff".freeze
+  APPLY_B = "noop-b.diff".freeze
+  APPLY_C = "noop-c.diff".freeze
+
+  def formula(name = "formula_name", path: Formulary.core_path(name), spec: :stable, alias_path: nil, &block)
+    Class.new(Formula) {
+      url TESTBALL_URL
+      sha256 TESTBALL_SHA256
+      class_eval(&block)
+    }.new(name, path, spec, alias_path: alias_path)
+  end
+
+  matcher :be_patched do
+    match do |formula|
+      shutup do
+        formula.brew do
+          formula.patch
+          s = File.read("libexec/NOOP")
+          expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected"
+          expect(s).to include("ABCD"), "libexec/NOOP was not patched as expected"
+        end
+      end
+    end
+  end
+
+  matcher :be_sequentially_patched do
+    match do |formula|
+      shutup do
+        formula.brew do
+          formula.patch
+          s = File.read("libexec/NOOP")
+          expect(s).not_to include("NOOP"), "libexec/NOOP was not patched as expected"
+          expect(s).not_to include("ABCD"), "libexec/NOOP was not patched as expected"
+          expect(s).to include("1234"), "libexec/NOOP was not patched as expected"
+        end
+      end
+    end
+  end
+
+  matcher :miss_apply do
+    match do |formula|
+      expect {
+        shutup do
+          formula.brew do
+            formula.patch
+          end
+        end
+      }.to raise_error(MissingApplyError)
+    end
+  end
+
+  specify "single_patch" do
+    expect(
+      formula do
+        def patches
+          PATCH_URL_A
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "single_patch_dsl" do
+    expect(
+      formula do
+        patch do
+          url PATCH_URL_A
+          sha256 PATCH_A_SHA256
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "single_patch_dsl_with_apply" do
+    expect(
+      formula do
+        patch do
+          url TESTBALL_PATCHES_URL
+          sha256 TESTBALL_PATCHES_SHA256
+          apply APPLY_A
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "single_patch_dsl_with_sequential_apply" do
+    expect(
+      formula do
+        patch do
+          url TESTBALL_PATCHES_URL
+          sha256 TESTBALL_PATCHES_SHA256
+          apply APPLY_A, APPLY_C
+        end
+      end,
+    ).to be_sequentially_patched
+  end
+
+  specify "single_patch_dsl_with_strip" do
+    expect(
+      formula do
+        patch :p1 do
+          url PATCH_URL_A
+          sha256 PATCH_A_SHA256
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "single_patch_dsl_with_strip_with_apply" do
+    expect(
+      formula do
+        patch :p1 do
+          url TESTBALL_PATCHES_URL
+          sha256 TESTBALL_PATCHES_SHA256
+          apply APPLY_A
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "single_patch_dsl_with_incorrect_strip" do
+    expect {
+      shutup do
+        f = formula do
+          patch :p0 do
+            url PATCH_URL_A
+            sha256 PATCH_A_SHA256
+          end
+        end
+
+        f.brew { |formula, _staging| formula.patch }
+      end
+    }.to raise_error(ErrorDuringExecution)
+  end
+
+  specify "single_patch_dsl_with_incorrect_strip_with_apply" do
+    expect {
+      shutup do
+        f = formula do
+          patch :p0 do
+            url TESTBALL_PATCHES_URL
+            sha256 TESTBALL_PATCHES_SHA256
+            apply APPLY_A
+          end
+        end
+
+        f.brew { |formula, _staging| formula.patch }
+      end
+    }.to raise_error(ErrorDuringExecution)
+  end
+
+  specify "patch_p0_dsl" do
+    expect(
+      formula do
+        patch :p0 do
+          url PATCH_URL_B
+          sha256 PATCH_B_SHA256
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "patch_p0_dsl_with_apply" do
+    expect(
+      formula do
+        patch :p0 do
+          url TESTBALL_PATCHES_URL
+          sha256 TESTBALL_PATCHES_SHA256
+          apply APPLY_B
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "patch_p0" do
+    expect(
+      formula do
+        def patches
+          { p0: PATCH_URL_B }
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "patch_array" do
+    expect(
+      formula do
+        def patches
+          [PATCH_URL_A]
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "patch_hash" do
+    expect(
+      formula do
+        def patches
+          { p1: PATCH_URL_A }
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "patch_hash_array" do
+    expect(
+      formula do
+        def patches
+          { p1: [PATCH_URL_A] }
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "patch_string" do
+    expect(formula { patch PATCH_A_CONTENTS }).to be_patched
+  end
+
+  specify "patch_string_with_strip" do
+    expect(formula { patch :p0, PATCH_B_CONTENTS }).to be_patched
+  end
+
+  specify "patch_data_constant" do
+    expect(
+      formula("test", path: Pathname.new(__FILE__).expand_path) do
+        def patches
+          :DATA
+        end
+      end,
+    ).to be_patched
+  end
+
+  specify "single_patch_missing_apply_fail" do
+    expect(
+      formula do
+        def patches
+          TESTBALL_PATCHES_URL
+        end
+      end,
+    ).to miss_apply
+  end
+
+  specify "single_patch_dsl_missing_apply_fail" do
+    expect(
+      formula do
+        patch do
+          url TESTBALL_PATCHES_URL
+          sha256 TESTBALL_PATCHES_SHA256
+        end
+      end,
+    ).to miss_apply
+  end
+
+  specify "single_patch_dsl_with_apply_enoent_fail" do
+    expect {
+      shutup do
+        f = formula do
+          patch do
+            url TESTBALL_PATCHES_URL
+            sha256 TESTBALL_PATCHES_SHA256
+            apply "patches/#{APPLY_A}"
+          end
+        end
+
+        f.brew { |formula, _staging| formula.patch }
+      end
+    }.to raise_error(ErrorDuringExecution)
+  end
+end
+
+__END__
+diff --git a/libexec/NOOP b/libexec/NOOP
+index bfdda4c..e08d8f4 100755
+--- a/libexec/NOOP
++++ b/libexec/NOOP
+@@ -1,2 +1,2 @@
+ #!/bin/bash
+-echo NOOP
+\ No newline at end of file
++echo ABCD
+\ No newline at end of file
diff --git a/Library/Homebrew/test/patching_test.rb b/Library/Homebrew/test/patching_test.rb
deleted file mode 100644
index 3dacc0818bebb180fa1fef956c409a1960cd1ce0..0000000000000000000000000000000000000000
--- a/Library/Homebrew/test/patching_test.rb
+++ /dev/null
@@ -1,248 +0,0 @@
-require "testing_env"
-require "formula"
-
-class PatchingTests < Homebrew::TestCase
-  TESTBALL_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz".freeze
-  TESTBALL_PATCHES_URL = "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1-patches.tgz".freeze
-  PATCH_URL_A = "file://#{TEST_FIXTURE_DIR}/patches/noop-a.diff".freeze
-  PATCH_URL_B = "file://#{TEST_FIXTURE_DIR}/patches/noop-b.diff".freeze
-  PATCH_A_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-a.diff"
-  PATCH_B_CONTENTS = File.read "#{TEST_FIXTURE_DIR}/patches/noop-b.diff"
-  APPLY_A = "noop-a.diff".freeze
-  APPLY_B = "noop-b.diff".freeze
-  APPLY_C = "noop-c.diff".freeze
-
-  def formula(*args, &block)
-    super do
-      url TESTBALL_URL
-      sha256 TESTBALL_SHA256
-      class_eval(&block)
-    end
-  end
-
-  def assert_patched(formula)
-    shutup do
-      formula.brew do
-        formula.patch
-        s = File.read("libexec/NOOP")
-        refute_includes s, "NOOP", "libexec/NOOP was not patched as expected"
-        assert_includes s, "ABCD", "libexec/NOOP was not patched as expected"
-      end
-    end
-  end
-
-  def assert_sequentially_patched(formula)
-    shutup do
-      formula.brew do
-        formula.patch
-        s = File.read("libexec/NOOP")
-        refute_includes s, "NOOP", "libexec/NOOP was not patched as expected"
-        refute_includes s, "ABCD", "libexec/NOOP was not patched as expected"
-        assert_includes s, "1234", "libexec/NOOP was not patched as expected"
-      end
-    end
-  end
-
-  def assert_missing_apply_fail(formula)
-    assert_raises(MissingApplyError) do
-      shutup do
-        formula.brew do
-          formula.patch
-        end
-      end
-    end
-  end
-
-  def test_single_patch
-    assert_patched formula {
-      def patches
-        PATCH_URL_A
-      end
-    }
-  end
-
-  def test_single_patch_dsl
-    assert_patched formula {
-      patch do
-        url PATCH_URL_A
-        sha256 PATCH_A_SHA256
-      end
-    }
-  end
-
-  def test_single_patch_dsl_with_apply
-    assert_patched formula {
-      patch do
-        url TESTBALL_PATCHES_URL
-        sha256 TESTBALL_PATCHES_SHA256
-        apply APPLY_A
-      end
-    }
-  end
-
-  def test_single_patch_dsl_with_sequential_apply
-    assert_sequentially_patched formula {
-      patch do
-        url TESTBALL_PATCHES_URL
-        sha256 TESTBALL_PATCHES_SHA256
-        apply APPLY_A, APPLY_C
-      end
-    }
-  end
-
-  def test_single_patch_dsl_with_strip
-    assert_patched formula {
-      patch :p1 do
-        url PATCH_URL_A
-        sha256 PATCH_A_SHA256
-      end
-    }
-  end
-
-  def test_single_patch_dsl_with_strip_with_apply
-    assert_patched formula {
-      patch :p1 do
-        url TESTBALL_PATCHES_URL
-        sha256 TESTBALL_PATCHES_SHA256
-        apply APPLY_A
-      end
-    }
-  end
-
-  def test_single_patch_dsl_with_incorrect_strip
-    assert_raises(ErrorDuringExecution) do
-      shutup do
-        formula do
-          patch :p0 do
-            url PATCH_URL_A
-            sha256 PATCH_A_SHA256
-          end
-        end.brew { |f, _staging| f.patch }
-      end
-    end
-  end
-
-  def test_single_patch_dsl_with_incorrect_strip_with_apply
-    assert_raises(ErrorDuringExecution) do
-      shutup do
-        formula do
-          patch :p0 do
-            url TESTBALL_PATCHES_URL
-            sha256 TESTBALL_PATCHES_SHA256
-            apply APPLY_A
-          end
-        end.brew { |f, _staging| f.patch }
-      end
-    end
-  end
-
-  def test_patch_p0_dsl
-    assert_patched formula {
-      patch :p0 do
-        url PATCH_URL_B
-        sha256 PATCH_B_SHA256
-      end
-    }
-  end
-
-  def test_patch_p0_dsl_with_apply
-    assert_patched formula {
-      patch :p0 do
-        url TESTBALL_PATCHES_URL
-        sha256 TESTBALL_PATCHES_SHA256
-        apply APPLY_B
-      end
-    }
-  end
-
-  def test_patch_p0
-    assert_patched formula {
-      def patches
-        { p0: PATCH_URL_B }
-      end
-    }
-  end
-
-  def test_patch_array
-    assert_patched formula {
-      def patches
-        [PATCH_URL_A]
-      end
-    }
-  end
-
-  def test_patch_hash
-    assert_patched formula {
-      def patches
-        { p1: PATCH_URL_A }
-      end
-    }
-  end
-
-  def test_patch_hash_array
-    assert_patched formula {
-      def patches
-        { p1: [PATCH_URL_A] }
-      end
-    }
-  end
-
-  def test_patch_string
-    assert_patched formula { patch PATCH_A_CONTENTS }
-  end
-
-  def test_patch_string_with_strip
-    assert_patched formula { patch :p0, PATCH_B_CONTENTS }
-  end
-
-  def test_patch_data_constant
-    assert_patched formula("test", Pathname.new(__FILE__).expand_path) {
-      def patches
-        :DATA
-      end
-    }
-  end
-
-  def test_single_patch_missing_apply_fail
-    assert_missing_apply_fail formula {
-      def patches
-        TESTBALL_PATCHES_URL
-      end
-    }
-  end
-
-  def test_single_patch_dsl_missing_apply_fail
-    assert_missing_apply_fail formula {
-      patch do
-        url TESTBALL_PATCHES_URL
-        sha256 TESTBALL_PATCHES_SHA256
-      end
-    }
-  end
-
-  def test_single_patch_dsl_with_apply_enoent_fail
-    assert_raises(ErrorDuringExecution) do
-      shutup do
-        formula do
-          patch do
-            url TESTBALL_PATCHES_URL
-            sha256 TESTBALL_PATCHES_SHA256
-            apply "patches/#{APPLY_A}"
-          end
-        end.brew { |f, _staging| f.patch }
-      end
-    end
-  end
-end
-
-__END__
-diff --git a/libexec/NOOP b/libexec/NOOP
-index bfdda4c..e08d8f4 100755
---- a/libexec/NOOP
-+++ b/libexec/NOOP
-@@ -1,2 +1,2 @@
- #!/bin/bash
--echo NOOP
-\ No newline at end of file
-+echo ABCD
-\ No newline at end of file