MSTest单元测试自行通过,在运行其他测试时失败

时间:2010-06-07 17:15:24

标签: c# unit-testing mstest

我遇到了一些MSTest单元测试的麻烦,当我单独运行它们时会通过,但是当我运行整个单元测试类时会失败。测试测试了SLaks helped me with earlier的一些代码,他警告我,我在做什么不是线程安全的。但是,现在我的代码更复杂,我不知道如何使其成为线程安全的。这就是我所拥有的:

public static class DLLConfig
{
    private static string _domain;

    public static string Domain
    {
        get
        {
            return _domain = AlwaysReadFromFile
                ? readCredentialFromFile(DOMAIN_TAG)
                : _domain ?? readCredentialFromFile(DOMAIN_TAG);
        }
    }
}

我的测试很简单:

string expected = "the value I know exists in the file";
string actual = DLLConfig.Domain;
Assert.AreEqual(expected, actual);

当我自己运行此测试时,它会通过。当我将它与测试类中的所有其他测试(在不同属性上执行类似检查)一起运行时,actualnull并且测试失败。我注意到,对于类型为自定义Enum类型的属性,这不是问题。也许我对Domain属性有这个问题,因为它是string?或者这可能是MSTest如何工作的多线程问题?

4 个答案:

答案 0 :(得分:6)

我怀疑其他测试正在修改DLLConfig类中导致getter结果发生变化的一些值。单元测试应该始终从已知的初始状态运行,因此您应该在测试方法本身或在每次测试之前运行的TestInitialize属性标记的方法中设置它。

答案 1 :(得分:5)

您的测试取决于外部文件。而不是调用直接访问该文件的函数,您应该让DLLConfig.Domain调用另一个类中的方法。

public static string Domain
{
    get
    {
        return _domain = AlwaysReadFromFile
            ? CredentialReader.Read(DOMAIN_TAG)
            : _domain ?? CredentialReader.Read(DOMAIN_TAG);
    }
}

然后,您可以使用mock / fake / stub CredentialReader初始化DllConfig,您可以在其中控制其返回值。请记住,您正在测试DLLConfig.Domain是否根据AlwaysReadFromFile条件返回正确的值。您不应该同时测试该值的来源(或者甚至是否存在)。

让您的DLLConfig类更“可测试”,可以分离出各种问题。当你想到一个课时,不禁要说“这个课 AND 那个”(抽象配置数据并阅读来自文件的数据)这是一个很好的选择,该课程正在混合关注并试图做很多事情。如果DLLConfig是配置数据的抽象,那么它应该只关注它并将数据从哪里留到另一个类。

答案 2 :(得分:1)

如果上述答案都不适合您,我通过在失败测试中断言之前添加Thread.Sleep(1)来解决此问题...

看起来在某处错过了测试同步...请注意我的测试不依赖于顺序,我没有任何静态成员也没有外部依赖。

答案 3 :(得分:0)

对我来说,问题在于使用了非线程安全的集合。当我切换到使用BlockingCollection(而不是List)时,一切都变得正确了。