测试订单Microsoft.VisualStudio.TestTools.UnitTesting问题?

时间:2014-04-18 16:23:40

标签: c# visual-studio unit-testing

我有一些测试代码似乎用完了正确的顺序。

[TestClass]
public class DirTest {
  public DirTest() {
    Assert.AreEqual( Directory.Exists( "testpath" ), true );
  }

  [TestMethod]
  public void TestMethod1() {
  }

  [ClassInitialize]
  public static void InitTest( TestContext context ) {
    Directory.CreateDirectory( "testpath" );
  }
}

它抛出一个错误,该目录不存在,不应该在调用类构造函数之前运行ClassInitialize,或者我需要做的事情是缺少的。如果不是这种情况,那么还有一个除了AssemblyInitialize之外的测试用例,它可以包含在构造类之前调用​​的测试中吗?

- 编辑 真正的问题在于,顶部是简化。

//RealClass.cs
public class RealClass{
  public RealClass( string path ){
    this._path = path;
    this._InitDirectory();
  }

  protected string _path;
  protected void _InitDirectory(){
    //Something that requires read from path
    File.WriteAllText( this._path + "/realData.data", "some real data that needs to be created by the class" );
  }
}

//DirTest.cs
[TestClass]
public class DirTest : RealClass {
  public DirTest() : base( "testpath" ) {}

  [TestMethod]
  public void TestMethod1() {
  }

  [ClassInitialize]
  public static void InitTest( TestContext context ) {
    Directory.CreateDirectory( "testpath" );
  }
}

单元测试将失败,因为需要路径的目录将在" ClassInitialize"之前消失。调用方法来创建所需的模拟目录。

- 编辑

我已经想出了解决这个问题的方法,但我仍然想知道是否有其他方法可以在不添加更多类的情况下实现所需的结果,并且不会删除测试的功能。我已经设置了一个" AssemblyInitialize"到一个只包含该静态方法的类,并告诉该方法为" ClassInitialize"触发静态方法。它当然会在任何构造者之前解雇。虽然问题的根源仍未解决,因为它不是自包含的,而是依赖于类函数来调用类设置。

2 个答案:

答案 0 :(得分:0)

按如下方式更新您的代码:

[TestClass]
public class DirTest {
  public DirTest() { }

  [TestMethod]
  public void TestMethod1() {
  }

  [ClassInitialize]
  public static void InitTest( TestContext context ) {
            if (!Directory.Exists( "testpath" )) {
                Directory.CreateDirectory( "testpath" );
            }
  }
}

答案 1 :(得分:0)

您尝试使用从SUT类派生[TestClass]的方法来访问受保护的方法。

首先:你真正需要的是什么?在您发布的代码中,没有明确尝试访问SUT的受保护成员的测试。因此,您可能会使事情变得比他们需要的更困难。

现在,如果实际上需要在此SUT类中测试受保护的成员,那么您是否考虑过创建一个继承自SUT类的类 - 一个不属于该类的类[TestClass]?例如:

//RealClass.cs
public class RealClass{
    public RealClass( string path ){
        this._path = path;
        this._InitDirectory();
    }

    protected string _path;
    protected void _InitDirectory(){
        //Something that requires read from path
        File.WriteAllText( this._path + "/realData.data", "some real data that needs to be created by the class" );
   }
}

// TestableRealClass.cs - Only used by the unit test
public class TestableRealClass: RealClass {
    public TestableRealClass(string path) : base(path) { }        

    public string Path {
        get {
            return _path;
        }
    }

    public InitDirectory() {
        _InitDirectory();
    }
}

//DirTest.cs
[TestClass]
public class DirTest {

    [TestMethod]
    public void TestMethod1() {
        var testPath = @"C:\SomePath";

        if (!Directory.Exists( testPath )) {
            Directory.CreateDirectory( testPath );
        }

        var sut = new TestableRealClass(testPath);

        AssertThatTheFileContainsExpectedStuff(testPath);
    }

    [TestMethod]
    public void TestAProtectedMember() {
        var testPath = @"C:\SomePath";

        if (!Directory.Exists( testPath )) {
            Directory.CreateDirectory( testPath );
        }

        var sut = new TestableRealClass(testPath);

        Assert.AreEqual(testPath, sut.Path);
    }

    private void AssertThatTheFileContainsExpectedStuff(string path) {
        // Do the assertion...
    }
}

这样您就不必担心文本夹具初始化的顺序,并且您的测试变得更容易理解。