如何通过testfixture参数运行测试方法?

时间:2012-10-13 19:51:49

标签: c# .net unit-testing nunit nunit-2.5

我有一个测试类和一个类如下。

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的属性?

1 个答案:

答案 0 :(得分:5)

这真的不是TestFixture的预期用途...如果您不想使用if,为什么不在测试中明确?您可以使用TestCase表示您希望通过某项测试的值。

[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

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

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

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


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

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的含义,即使用特定配置选项在灯具中运行所有测试。它可能不适合您的实际情况,但希望这两个想法能为您指明方向。