【问题标题】:Initializing class C#初始化类 C#
【发布时间】:2012-10-09 22:49:07
【问题描述】:

什么是初始化类并将初始化保存在一个变量中以供其他方法使用而不是每次都初始化的最佳方法。

这是我的代码:

private Employee employee;
public Employee SystemUnderTest
{
   get 
   {
       if (employee == null)
       {
          employee = new Employee();
       }
      return employee;
   }
}

//..method1 Test1
   public void TestMethod1()
   {
     Assert.IsTrue(SystemUnderTest.IsActive());
   }

   //..method2 Test   
   public void TestMethod2()
   {
     Assert.IsTrue(SystemUnderTest.IsEmployeeExists());
   }

PS:调试时我注意到它确实使用每个方法初始化了 Employee 对象。

使用 3.5 框架。

【问题讨论】:

  • 您的测试方法应该相互独立。在 C#/.NET 中创建对象非常快。您是否发现一些性能问题?
  • 不是真的,但我认为不初始化的唯一原因是因为我有从外部源读取一些数据的基类..
  • 您使用的是什么单元测试框架? NUnit, XUnit, mstest, ... ?
  • 运行单元测试时不应该有任何外部 IO。否则它们不是单元测试而是集成测试。我建议你模拟部分获取外部数据的代码。
  • 看看haacked.com/archive/2008/07/22/unit-test-boundaries.aspx 讨论使用外部数据IO进行单元测试

标签: c# unit-testing tdd mstest


【解决方案1】:

静态初始化应该可以工作。 这将在您第一次访问该类型时运行,并且共享变量将可用于所有实例。

private static bool m_HasInitialized = false;

private static MyClassName()
{
    // Do Stuff...
    m_HasInitialized = true;
}

【讨论】:

  • 这样,如果测试正在修改 Employee 实例,则该实例在运行特定测试方法时的状态将取决于之前运行的测试。
  • @PetarRepac 这是一件坏事,因为测试可以按任何顺序运行。
【解决方案2】:

如果我正确理解您的问题,请在您的测试类中创建一个私有字段来保存包含初始化信息的变量,然后使用带有 [TestInitialize] 或 [TestSetUp] 属性的方法(取决于您的测试框架)来初始化信息。这将使您的所有测试方法都可以看到私有字段,但您只需在一个地方定义初始化。这还具有为每个测试方法重新初始化变量的额外好处,这样如果一个测试意外地改变了变量的状态,它不应该导致其他测试中断。

但如果您真的希望初始化只发生一次(而不是只定义一次代码),请使用 [TestFixtureSetUp] 或 [ClassInitialize] 属性。

【讨论】:

  • 我确实尝试了ClassInitialize 属性,但是当我运行我的测试时,它显示所有测试都被跳过了......我的测试都没有运行......有什么想法吗? ——
  • 您是否熟悉在当前上下文或解决方案中运行或调试测试之间的区别?您需要确保执行正确的操作。如果您已经了解所有这些,有时您可以创建您通过 Visual Studio 中的“测试”菜单管理的测试列表,并且可能已经定义了一些不充分的测试集,其中不包括您的任何测试想跑。不过,我现在正在深入猜测。
【解决方案3】:

您可以在类静态构造函数中初始化一个静态字段,也可以使用[ClassInitialize]* 单元测试属性来标记您希望在该单元测试类中的任何测试方法执行之前执行的方法。

更多信息在这里:Do you use TestInitialize or the test class constructor to prepare each test? and why?

【讨论】:

  • 也许 OP 不使用 mstest ?
  • 我没想到ClassInitialize 我会试一试的。
  • 我确实尝试过使用 ClassInitialize 属性,但是当我运行我的测试时,它显示所有测试都被跳过了......我的测试都没有运行......有什么想法吗?
【解决方案4】:

单例模式(变体之一,延迟初始化):

public class Singleton
{
    private readonly static object _lockObject = new object();
    private static Singleton _instance;

    public static Singleton Instance {
        get
        {
            if (_instance == null)
            {
                lock (_lockObject)
                {
                    if (_instance == null)
                        _instance = new Singleton();
                }
            }
            return _instance;
        }
    }
}

【讨论】:

  • 为什么懒惰?没有必要。它使代码复杂化,初始化代码最终还是会被调用。
  • 公平的,然后是 private static volatile Singleton _instance = new()...;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-17
  • 2020-08-19
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多