你使用TestInitialize或者testing类构造函数来准备每个testing吗? 为什么?

这个问题关于在Visual Studio中使用MSTest进行unit testing(这很重要,因为MSTest的执行顺序 )。 标记为[TestInitialize]的方法和testing类构造函数都将在每个testing方法之前运行。

所以,问题是,你在这些领域都倾向于做什么? 你是否避免从事某些活动? 你的理由是什么:风格,技术,迷信?

构造函数只是由语言提供的结构。 每个testing框架似乎都有自己的受控生命周期“初始化”。 你可能会遇到麻烦,使用构造函数来改变你的本地人。

MSTest:为每个TestMethod获得一个完整的testing类实例。 这可能是唯一可以在构造函数,初始化方法或testing方法中改变本地语言而不影响其他testing方法的情况。

 public class TestsForWhatever { public TestsForWhatever() { // You get one of these per test method, yay! } [TestInitialize] public void Initialize() { // and one of these too! } [TestMethod] public void AssertItDoesSomething() { } [TestMethod] public void AssertItDoesSomethingElse() { } } 

MSpec:你只得到一个EstablishBecause你所有的断言( It )。 所以,不要在你的断言中改变你的本地人。 而且不要依赖基本上下文中的本地variables(如果使用它们的话)。

 [Subject(typeof(Whatever))] public class When_doing_whatever { Establish context = () => { // one of these for all your Its }; Because of = () => _subject.DoWhatever(); It should_do_something; It should_do_something_else; } 

使用TestInitialize()或ClassInitialize()而不是testing类实例或静态构造函数的主要优点是显式的。 它清楚地表明你在testing之前正在做一些设置。 一直这样做,应该从长远来看提高可维护性。

以下是我在TestInitialize中find的一些优点。

  • 一些环境variables(例如TestContext)在testing类被实例化之前是不可访问的。
  • 通过标记一个基本的TestInitialize方法摘要,可以要求派生类的实现。
  • 可以轻松地覆盖基本的TestInitialize方法,并确定是否在派生的impl之前,之后或根本调用基本impl。 相比之下,如果从基础testing类派生testing类,则在无参数构造函数的情况下,无论您是否打算使用基础testing类,都会调用基础testing类。
  • 其明确的定义使得意图清晰,并且补充了TestCleanup方法。 您可能会争辩说,您可以为每个构造函数创build一个析构函数,但不能保证MS Test能像您期望的那样处理析构函数。

我更喜欢使用[TestInitialize]方法来执行被testing对象的实例化以及它的参数。 如果需要实例化一个testing基类(通常是在创build或刷新存储库的地方等),我只在构造函数中执行工作。 这有助于我保持testing框架代码和testing代码在逻辑上和物理上分离。

这个问题也被问到(稍后) 在VStesting框架中使用构造函数与TestInitialize()属性之间有什么区别?

FWIW我假设“类构造函数”是指实例构造函数 (而不是静态构造函数 )。

我相信你问同样的问题同样可以问静态构造函数与ClassInitialize …

您testing的对象不需要在[TestInitialize]方法中实例化。 你可以在一个testing方法[Test]中testing你的对象的构造函数。

[TestInitialize]中的对象可以设置你的持久性存储或者准备被测对象在testing中使用的值。

我说使用构造函数,除非你需要TestContext

  1. 如果你能保持简单,为什么不呢。 构造函数比魔法属性更简单。
  2. 你可以使用readonly ,这在testing初始化​​中是一件很大的事情,你要为那些不应该改变的testing准备东西(理想情况下你准备的东西也是不可变的)。

这取决于场景。 如果你有一个testing类,并且出于一些奇怪的原因,如果你需要在另一个testing类上创build它的实例,你将需要使用构造函数。

否则testing初始化​​更符合概念。 首先,同样的原因写在上面,第二个MS可以在这个属性上引入更多的特性,你将受益于他们,构造函数你将卡在它。