我正在使用C#和.NET框架4编写一个绿色的字段项目,因为我的上一个应用程序由于缺乏测试而没有一个非常可测试的设计,我决心避免这次犯同样的错误。
我已经为注入到类中的接口中的每个类都有外部依赖项,现在我正在编写具体的实现。虽然我不打算开始编写单元测试来测试框架中的代码,但我担心如果我调用框架类的方式存在错误,那么我就无法测试它。作为一个非常简单的例子,我可以说我正在使用SQLCommand(我实际上使用的是EF 4.1,但这仅仅是一个例子)我忘了在命令中设置连接属性。我的想法是,如果我嘲笑某些框架类,我可以通过模拟测试这些约定,并避免潜在的错误来源。这样做也意味着我模拟了一些难以测试的框架类中的某些异常但是确实发生了例如UnauthorizedAccessException,OutOfMemoryException等。
我意识到代码可能会在我尝试运行代码进行测试时破解但是我脑子里有些东西告诉我,我仍然有可能错过一些东西,只有在产品发现后才能找到它在外地。这样做是否有任何理由,或者这是YAGNI的一个相当严重的案例?
答案 0 :(得分:0)
我认为在模拟类中有相当大的价值,因此可以引入难以激发的错误,从而正确测试错误路径。
我没有看到框架如何模拟“忘记设置xxx”错误。你的模拟需要“知道”框架期望在findThing()之前调用setConnection(),以捕获模拟整个框架所需的那些错误。
我认为您需要查看单元测试 - 运用您自己的代码路径 - 这可以从使用模拟和集成测试中受益,模拟和集成测试测试不同组件的交互,例如您的代码与框架。
在这两种情况下你都可以使用相同的测试驱动程序(我是Java,所以对我来说是JUnit),但测试策略是不同的。要清楚你正在做哪种测试。
答案 1 :(得分:0)
创建注入接口的具体模拟太过分了。您不应该模拟整个框架。但是,您应该检查代码路径并确保正确处理异常和无效输入。
大多数模拟框架(如Rhino Mocks)允许您模拟从注入的模拟对象中抛出异常。
[Test]
public void testThrowsExceptions()
{
// Arrange
var dependency1 = MockRepository.Mock<IMockFrameworkObject1>();
var dependency2 = MockRepository.Mock<IMockFrameworkObject2>();
dependency2.Expect(d2 => d2.SomeAction).Throws(new someexception);
var myObject = new ConcreteObject(dependency1, dependency2);
// Act
myObject.SomeAction();
// Assert
}
答案 2 :(得分:0)
您可以使用Moles来模拟框架方法调用。 以下是它用于数据库的方式:Use Mole to unit test SQLDataReader