1

我正在设计一个能够将 DataSource 从 SQL 更改为 Oracle 和 SQLite 的解决方案。

为此,我使用 Unity 框架来实现延迟绑定。

我创建了一个接口并将所有数据库方法签名写入其中。

现在我正在为每个数据源编写单独的类(项目)并实现这个接口。

我现在想要的是创建一个测试项目,它应该确保接口中定义的所有方法都必须在测试项目中采用,这个测试项目有单独的测试数据库

是否有任何框架/模式可用于自动强制创建测试方法。

如果有人提供在方法上编写 [TestMethod] 属性(实现接口时)并将返回类型更改为 Void ,我认为这就足够了。

我真正想要的是实现一个测试项目,该项目应该强制为数据库层接口中定义的所有签名创建测试方法。

我使用 VS 2012 作为开发环境。

如果我没有任何现成的解决方案,我如何使用反射来实现方法来测试项目并在设计时更改其签名。(这是奇怪的要求吗?)

如果需要更多详细信息,请告诉我。

欢迎提出建议。

4

2 回答 2

1

我不知道这里有任何特定的模式,但我为这种情况做的是:

  1. 将接口所在的项目引用到测试项目中
  2. 在 CRUDProviderMock.cs 或类似的东西中实现接口
  3. 使用模拟类进行测试

我相信我不是唯一这样做的人,因为我看到许多公司都在应用这种做法。

示例项目在这里: https ://databaselayertesting.codeplex.com/

示例项目使用存储库模式NUnit 框架进行测试,其中:

  1. IRepository 是数据库的 CRUD 接口
  2. EntityOne 是示例数据库实体
  3. EntityOneRepositoryMock 是使用列表的模拟 IRepository 实现

您可以使用示例数据库而不是列表来模拟真实的数据库行为。

于 2013-04-22T09:12:59.320 回答
0

我确实意识到这个问题很老了,我的解决方案既不针对 VS2012,也不针对 NUnit 早期版本的限制。但是,我发现您的问题与现代环境中的其他问题完全相同。我也偶然发现了这一点,并找到了一个合适的解决方案,我认为可能适合其他人或我未来的自己,来满足您的要求:

我现在想要的是创建一个测试项目,它应该确保必须采用接口中定义的所有方法......

是否有任何框架/模式可用于自动强制创建测试方法。

通过TestCaseSource与适配器模式结合使用,我能够强制接口的任何后续更改都将使程序员也必须更新测试。反对使用反射的好处在于,这会给您带来早期的编译时错误,并且通过运行特定的测试更容易追踪测试错误。

下面的代码非常示意性。我自己的用途是将它与特定数据的模拟结合起来,testObject并验证是否总是抛出一些特定的异常。限制是testObject共享的设置,因此最适合更简单的场景。

测试代码:

[TestFixture()]
public class SpecificDatabaseTest : IDatabase
{
    private SpecificDatabase testObject = new SpecificDatabase();
    private object TestObject = new object();
    private SomeObject TestSomeObject1 = new SomeObject();
    private SomeObject TestSomeObject2 = new SomeObject();

    public IEnumerable<TestCaseData> SomeMethodData
    {
        get
        {
            yield return new TestCaseData(TestObject).Returns(TestObject);    
        }
    }

    public IEnumerable<TestCaseData> SomeOtherMethodData
    {
        get
        {
            yield return new TestCaseData(TestSomeObject1, TestSomeObject2).Returns(TestSomeObject2);
            yield return new TestCaseData(TestSomeObject2, TestSomeObject1).Returns(TestSomeObject1);
        }
    }

    [Test, TestCaseSource(nameof(SomeMethodData))]
    public object SomeMethod(object data)
    {
        return testObject.SomeMethod(data);
    }

    [Test, TestCaseSource(nameof(SomeOtherMethodData))]
    public SomeObject SomeOtherMethod(SomeObject data1, SomeObject data2)
    {
        return testObject.SomeOtherMethod(data1, data2);
    }
}

其他代码:

public interface IDatabase
{
    object SomeMethod(object data);

    SomeObject SomeOtherMethod(SomeObject data1, SomeObject data2);
}

public class SpecificDatabase : IDatabase
{
    public object SomeMethod(object data)
    {
        return data;
    }

    public SomeObject SomeOtherMethod(SomeObject data1, SomeObject data2)
    {
        return data2;
    }
}

public class SomeObject { }
于 2017-11-09T22:16:41.507 回答