【发布时间】:2021-08-19 22:40:19
【问题描述】:
全部,
我正在使用单元测试框架在 .net 中编写我的测试。我编写了一些单元测试,它们都访问了一个内部是静态类的配置对象(通过 AppConfig.Current)。
在启动时,我初始化了这个配置对象,并立即在下面的行中使用它,如下所示:
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext context)
{
var appCfg = AppConfig.Current;
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "conf/app.settings.xml");
appCfg.Load(path);
var _ = AccountingContext.Current; // <= AccountingContext references the configuration object via "AppConfig.Current" to read some configuration values and initialize the accounting context but I receive a different instance (ONLY in release mode) ....
}
加载配置后,下一行使用此配置对象(AccountingContext.Current)从配置对象初始化自身。 问题是,测试在 Debug 模式下运行良好,但在 Release 模式下,当我引用配置对象时,我得到了一个不同的对象(我知道这是事实,因为未加载配置)。
那么在发布模式的单元测试中使用静态引用有什么用???
更新:自行回答
发出的谎言在“AccountingContext”类中。 这个类也是一个静态的,它自己初始化是这样的:
public static AccountingContext Current { get; set; } = new AccountingContext();
public AccountingContext()
{
CompanyAccessContext = _CreateCompanyAccessContext();
}
将此初始化更改为使用静态 ctor 解决了此问题,现在一切正常:
public static AccountingContext Current { get; set; }
static AccountingContext()
{
Current = new AccountingContext();
}
public AccountingContext()
{
CompanyAccessContext = _CreateCompanyAccessContext();
}
看起来进行了优化,改变了 AccountingContext 的实际初始化流程。这有点不受欢迎,不知道这是不是每个人的期望。
我还发现了这个好资源: Static member variable not being initialized in Release - Compiler/clr bug?
【问题讨论】:
-
将该更新移至自我回答。
-
这篇文章没有问题。考虑转移到其他网站/博客,或者像@Nkosi 所说的那样转换成真正的问答。
-
@ActiveX “怎么了?”这不是一个真正的问题 - 这是一种模糊且无益的俗语 - 另外只有某些文化才容易理解 - 为了盎格鲁圈以外的用户的利益,请编辑您的帖子以更具体。
-
另外,我认为您误解了单元测试的实际用途。 单元测试不应依赖于任何外部资源或系统范围的状态。您通过从磁盘加载内容 (
appCfg.Load(path);) 打破了单元测试的主要规则。您应该将其重构为适当的 integration-test。 -
在下面发布答案并接受它。这是“自我回答”的唯一正确方法
标签: c# .net unit-testing