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

C# 如何通过testfixture参数运行测试方法?,c#,.net,unit-testing,nunit,nunit-2.5,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.

我有一个测试班和一个类似下面的班

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());
   }
}
公共类Foo
{
私人IDbOjbect_db;
公共设施(字符串连接)
{
_db=新的DbOjbect(康涅狄格州);
}
内部Foo(IDB对象数据库)
{
_db=db;
}
内部bool TestOne()
{
if(_db.CurrentDbType==DBType.Oracle)
{
//做点什么
返回true;
}
返回false;
}
内部bool TestTwo()
{
如果(_db.CurrentDbType==DBType.SqlServer ||
_db.CurrentDbType==DBType.SqlServerCE)
{
//做点什么
返回真值
}
返回false;
}
内部布尔测试三()
{
如果(_db.CurrentDbType==DBType.MySql ||
_db.CurrentDbType==DBType.PostgreSQL | |
_db.CurrentDbType==DBType.SQLite)
{
//做点什么
返回真值
}
返回false;
}
公共进程()
{
TestOne();
TestTwo();
测试三();
}
}
[TestFixture(“sqlserver”)]
[TestFixture(“sqlserverce”)]
[测试夹具(“oracle”)]
[TestFixture(“mysql”)]
[测试夹具(“sqlite”)]
[测试夹具(“postgre”)]
公开课考试
{
专用字符串连接;
私人福福,;
公共测试(字符串连接)
{
_conn=conn;
}
[设置]
公共作废设置()
{
db=新的Mock();
开关(连接)
{
案例“sqlserver”:
Setup(x=>x.CurrentDbType).Returns(DBType.SqlServer);
打破
案例“sqlserverce”:
Setup(x=>x.CurrentDbType).Returns(DBType.SqlServerCE);
打破
案例“mysql”:
Setup(x=>x.CurrentDbType).Returns(DBType.MySql);
打破
案例“postgre”:
Setup(x=>x.CurrentDbType).Returns(DBType.PostgreSQL);
打破
案例“sqlite”:
Setup(x=>x.CurrentDbType).Returns(DBType.SQLite);
打破
案例“甲骨文”:
Setup(x=>x.CurrentDbType).Returns(DBType.Oracle);
打破
}
f=新的Foo(db.Object);
}
[测试]
公共void TestOne()
{
Assert.IsTrue(f.TestOne());
}
[测试]
公共测试二()
{
Assert.IsTrue(f.TestTwo());
}
[测试]
公营部门
{
Assert.IsTrue(f.TestThree());
}
}
当_conn是oracle时,我希望运行TestOne方法。 当连接为sqlserver或sqlserverce时,我希望运行TestThree方法。 当连接为mysql、sqlite或postgre时,我希望运行TestTwo方法。
我该怎么做?这有nunit的属性吗

这确实不是
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) ...
这为您提供了测试应该失败的案例的额外好处。我不确定它是否符合您的实际情况,但除了预期的通过值之外,测试失败也是非常重要的


EDIT如果确实需要基于DB类型的
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());
    }
}
公共抽象类Foo{
受保护的IDbOjbect_db;
私有DBType_类型;
公共数据库类型{
获取{return\u type;}
}
公共Foo(DBType){
_类型=类型;
}
内部抽象bool RunTest();
公共void连接(IDbObject db){
_db=db;
}
公共静态Foo创建(字符串类型){
开关(类型){
案例“oracle”:返回新的FooImpl_oracle();
}
返回null;
}
}
公开密封类FooImpl_Oracle:Foo{
内部FooImpl_Oracle():base(DBType.Oracle){
}
内部bool运行测试(){
//做点什么
返回true;
}
}
[测试夹具(“oracle”)]
公开课考试{
私人福福,;
公共测试(字符串连接){
f=Foo.Create(conn);
}
[设置]
公共作废设置(){
Mock db=新Mock();
Setup(x=>x.CurrentDbType).Returns(f.Type);
f、 连接(db);
}
[测试]
公共void TestOne(){
Assert.IsTrue(f.RunTest());
}
}

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

使用
if
怎么样?我不想使用if。我想要更专业的东西,比如属性。你确实应该考虑组合
测试
,或者制作两个不同的
测试夹具
。原因是
TestFixture
旨在为每一组参数运行所有测试。如果只应用一个
测试
,则意味着两个测试本质上是相同的测试,或者整个
测试夹具
不同。顺便说一句,这可能有助于重新考虑您的对象模型;也许是错了?@Jared不。如果我决定使用If,我将不得不使用很多If。我认为,如果不专业,就要使用大量的if。@sinanakyazici如果是专业的,我会非常不同意
。大量丑陋的
if
和或
if
/
else
可能是另外一种情况,但可以说,基本决策结构之一是