2

我有一个测试课和一个像下面这样的课。

public class Foo
{
    private IDbOjbect _db;

    public Foo(string conn)
    {
        _db = new DbOjbect(conn);
    }

    internal Foo(IDbObject db)
    {
        _db= db;
    }

    internal bool TestOne()
    {
        if (_db.CurrentDbType == DBType.Oracle)
        {
            //do something
            return true;
        }
        return false;
    }

    internal bool TestTwo()
    {
        if (_db.CurrentDbType == DBType.SqlServer || 
            _db.CurrentDbType == DBType.SqlServerCE)
        {
            //do something
            return true
        }
        return false;
    }

    internal bool TestThree()
    {
        if (_db.CurrentDbType == DBType.MySql || 
            _db.CurrentDbType == DBType.PostgreSQL || 
            _db.CurrentDbType == DBType.SQLite)
        {
            //do something
            return true
        }
        return false;
    }

    public void RunProcesses()
    {
         TestOne();
         TestTwo();
         TestThree();
    }
}

[TestFixture("sqlserver")]
[TestFixture("sqlserverce")]
[TestFixture("oracle")]
[TestFixture("mysql")]
[TestFixture("sqlite")]
[TestFixture("postgre")]
public class Tests
{
   private string _conn;
   private Foo f;

   public Tests(string conn)
   {
       _conn = conn;
   }

    [SetUp]
    public void SetUp()
    {
        db = new Mock<IDbObject>();
        switch (_conn)
        {
            case "sqlserver":
                db.Setup(x => x.CurrentDbType).Returns(DBType.SqlServer);
                break;
            case "sqlserverce":
                db.Setup(x => x.CurrentDbType).Returns(DBType.SqlServerCE);
                break;
            case "mysql":
                db.Setup(x => x.CurrentDbType).Returns(DBType.MySql);
                break;
            case "postgre":
                db.Setup(x => x.CurrentDbType).Returns(DBType.PostgreSQL);
                break;
            case "sqlite":
                db.Setup(x => x.CurrentDbType).Returns(DBType.SQLite);
                break;
            case "oracle":
                db.Setup(x => x.CurrentDbType).Returns(DBType.Oracle);
                break;
        }

        f = new Foo(db.Object);
    }

   [Test]
   public void TestOne()
   {
       Assert.IsTrue(f.TestOne());
   }

   [Test]
   public void TestTwo()
   {
       Assert.IsTrue(f.TestTwo());
   }

   [Test]
   public void TestThree()
   {
       Assert.IsTrue(f.TestThree());
   }
}

当 _conn 是 oracle 时,我想运行 TestOne 方法。当 _conn 是 sqlserver 或 sqlserverce 时,我想运行 TestThree 方法。当 _conn 是 mysql、sqlite 或 postgre 时,我想运行 TestTwo 方法。我怎样才能做到这一点 ?是否有 nunit 的属性?

4

1 回答 1

5

这真的不是TestFixture... 如果您不想使用if,为什么不在测试中明确说明?您可以将 aTestCase用于您希望通过某个测试的值。

[TestFixture]
public class Tests {

    [TestCase("test1")]
    public void FooTest_One(String value) {
        Foo f = new Foo(value);
        Assert.IsTrue(f.TestOne());
        Assert.IsFalse(f.TestTwo());
    }

    [TestCase("test2")]
    public void FooTest_Two(String value) {
        Foo f = new Foo(value);
        Assert.IsTrue(f.TestTwo());
        Assert.IsFalse(f.TestOne());
    }
}

假设您要测试两个以上的值,您还可TestCase以为与预期行为相对应的值添加额外的 's:

[TestCase("test1")]
[TestCase("test1.1")]
public void FooTest_One(String value) ...

[TestCase("test2")]
[TestCase("test2.1")]
public void FooTest_Two(String value) ...

这为您提供了测试应该失败的案例的额外好处。我不确定它是否符合您的实际情况,但除了预期的通过值之外,测试失败总是很重要的。


编辑 如果您确实需要基于 DB 类型的类的动态行为Foo,最好的办法是创建一个抽象类来表示预期的行为。使用它,您的特定于数据库的实现将在运行时被调用。这是一个简短的示例:

public abstract class Foo {
    protected IDbOjbect _db;

    private DBType _type;
    public DBType Type {
        get { return _type; }
    }

    public Foo(DBType type) {
        _type = type;
    }

    internal abstract bool RunTest();

    public void Connect(IDbObject db) {
        _db = db;
    }

    public static Foo Create(String type) {
        switch (type) {
            case "oracle": return new FooImpl_Oracle();
        }

        return null;
    }
}

public sealed class FooImpl_Oracle : Foo {
    internal FooImpl_Oracle() : base(DBType.Oracle) {
    }

    internal bool RunTest() {
        //do something
        return true;
    }
}

[TestFixture("oracle")]
public class Tests {
    private Foo f;

    public Tests(string conn) {
        f = Foo.Create(conn);
    }

    [SetUp]
    public void SetUp() {
        Mock<IDbObject> db = new Mock<IDbObject>();
        db.Setup(x => x.CurrentDbType).Returns(f.Type);
        f.Connect(db);
    }

    [Test]
    public void TestOne() {
        Assert.IsTrue(f.RunTest());
    }
}

这将保留 的含义TestFixture,即使用特定配置选项运行夹具中的所有测试。它可能不完全适合您的实际情况,但希望这两个想法能给您一些方向。

于 2012-10-13T20:09:02.700 回答