我见过开发人员使用 Spring 的 @Autowired 特性使 Spring 框架负责在测试类或夹具中实例化和注入 SUT(被测系统)或 CUT(被测类)。以下是显示在测试夹具中使用的 @Autowired 的片段:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.ExpectedException;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.ContextConfiguration;
interface BackingStore
{
//Some methods
}
class Logger
{
public Logger(BackingStore backingStore)
{
//Capture input parameter into member variables
}
public void Log(String message)
{
//Some logic
}
}
@ContextConfiguration(locations = { "classpath:someconfig.xml" })
public class LoggerTests extends AbstractTestNGSpringContextTests
{
@Autowired
private Logger _logger;
@Test
@ExpectedException(NullPointerException)
public void Log_WhenPassedNull_ShouldThrowException()
{
_logger.Log(null);
}
}
SUT 所需的所有依赖项(递归)都指定为 Spring 配置 XML 文件的一部分。我不喜欢这种方法。我喜欢所有的测试(单元或集成)都像故事一样阅读(我听到 Kent Beck 说同样的话 :))。我喜欢在测试用例本身中实例化 SUT/CUT,即使它很复杂。这给出了关于测试用例的清晰画面。
我对@Autowired 或用于在测试夹具中注入 SUT 的任何自动注入机制几乎没有顾虑:
它降低了测试代码的可读性。@Autowire 看起来像魔术。AAA 的排列(Arrange-Act-Assert)从测试代码移动到 XML 文件。
它降低了测试代码的可维护性。这是因为#2。
在异常情况下无法有效验证 SUT/CUT 抛出异常的构造函数。我对此不是 100% 确定的。我不知道 Spring 框架是否对此有答案。
对于单元测试或集成测试来说,这似乎有点矫枉过正。
我在这个问题上向专家索要 2 美分。
谢谢。