使用Spring Framework的@Autowired在测试夹具中实例化和注入SUT(系统测试中)

时间:2012-12-17 16:11:12

标签: spring unit-testing testing dependency-injection integration-testing

我见过开发人员使用Spring的@Autowired功能,使Spring框架负责在测试类或fixture中实例化和注入SUT(System Under Test)或CUT(Class Under Test)。以下是显示@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文件的一部分。我不喜欢这种方法。我喜欢所有的测试(单元或集成)阅读就像一个故事(我听说肯特贝克说同样的事:))。我喜欢在测试用例中实例化SUT / CUT,即使它很复杂。这给出了关于测试用例的清晰图片。

我很少关注@Autowired或任何用于在测试夹具中注入SUT的自动注入机制:

  1. 它降低了测试代码的可读性。 @Autowire看起来像魔术。 AAA(Arrange-Act-Assert)的排列从测试代码移动到XML文件。

  2. 它降低了测试代码的可维护性。这是因为#2。

  3. 在特殊情况下无法有效验证SUT / CUT的构造函数抛出异常。我对此并不是100%肯定。我不知道Spring框架是否有答案。

  4. 对于单元测试或集成测试来说,这似乎有点过分了。

  5. 我请专家就这个问题花2美分。

    感谢。

1 个答案:

答案 0 :(得分:1)

如果您不知道在哪里查找@Autowired对象,它只会降低测试代码的可读性。我建议使用SpringJunitTestRunner,它在单元测试类的顶部定义测试应用程序上下文。

在测试用例中使用依赖注入可以让您轻松地使用不同的对象进行测试。

E.g。如果您的代码需要第三方服务,您可以使用依赖注入(例如,自动装配Spring bean)为您的单元测试和应用程序的实际服务注入模拟服务。

因此,definitley并没有降低测试代码的可维护性,因为它确实鼓励您测试的代码与任何外部对象之间的松散耦合。

可能以某种方式注入所有对象是一种过度杀伤,但对于单元测试/集成测试来说绝对不会有点过分。