I have been looking around the internet for a long, frustrating, while, and I'm still quite confused as to what the purpose of the teardown()
method is in MiniTest and how it should be used.
The basic gist I have is that it is 1-run after each test, and 2-undoes things that were done during the test in order to allow future tests to run in a clean environment.
However, I am unclear on the nature of things it needs to undo: Does it need to empty the DB? Reset class variables? etc.
I am also unclear on whether the method is supposed to be explicitly filled out or not. I have found many examples where teardown()
is completely left out of the example.
(My best guess is that there is a super-method teardown
that runs automatically and takes care of certain things. That would explain why it is often left out, and would also explain why some things are reset in a given teardown()
method and some aren't. But I still don't know which things are and which aren't.)
In short:
Does teardown need to be explicitly created? In what circumstances would it need to be overwritten and in which wouldn't it be?
The simplest answer is that you use #teardown
in every test but you don't need to worry about it. Similar to the Rails lifecycle, there is a Minitest lifecycle. There are hooks to inject logic and behavior to be used by your tests. The main one in Rails tests is the database transaction. Each test that uses ActiveSupport::TestCase
runs in a database transaction. The flow is like this:
Minitest::Test#setup
)MyTest#test_something
)Minitest::Test#teardown
)It is somewhat common for folks to use #setup
to create objects for use in tests. After the test method completes the test object is garbage collected, so most folks don't use #teardown
to clean up after the test. Because of this #teardown
is typically a more advanced feature that you don't normally use when writing tests. I see it used much more often in testing libraries that enhance Minitest.
But there are times I do use #teardown
in my tests. Here is an example of when I might use it.
require "minitest/autorun"
class Foo
def initialize namer
@namer = namer
end
def name
@namer.name
end
end
class FooTest < Minitest::Test
def setup
@namer_mock = Minitest::Mock.new
@namer_mock.expect :name, "foo"
@foo = Foo.new @namer_mock
end
def test_name
assert_equal "foo", @foo.name
end
def teardown
@namer_mock.verify
end
end