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