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、テストで明示的にしないのはなぜですか? 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());
    }
}

TestCase3 つ以上の値をテストする場合は、予想される動作に対応する値に を追加することもできます。

[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());
    }
}

TestFixtureこれにより、特定の構成オプションを使用してフィクスチャ内のすべてのテストを実行するという の意味が維持されます。あなたの実際の状況には正確に適合しないかもしれませんが、うまくいけば、これらの 2 つのアイデアが何らかの方向性を示してくれます。

于 2012-10-13T20:09:02.700 に答える