我该如何接近或不应该进行单元测试?

问题描述:

我有一个由别人编写的庞大的代码库,根本没有进行过单元测试。我想将单元测试添加到Spring应用程序中,但代码非常分离,有时代码不可测试。我应该如何处理这个问题,我应该从低级对象开始还是从高级开始,并且可以给我一个如何为Spring应用程序编写单元测试的示例。我该如何接近或不应该进行单元测试?

+1

解耦代码更容易测试,而不是更辛苦。太宽泛,不清楚你问的是什么。 – EJP

+0

我想测试一个具有一些自动装配依赖关系的spring类,并且这些类中也有一些自动装配的依赖项使用数据库,而其他的使用配置文件,我应该如何测试和模拟这些类。 –

您可以参考Integration Testing provided by Spring

这里下面是一个例子JUnit测试类,提供了测试用例的豆Spring上下文。

@ContextConfiguration(locations = { "/your-spring-cfg.xml" }) 
public class YourTest extends AbstractJUnit4SpringContextTests 
{ 
    @Autowired 
    private YourBean beanToTest; 

    @Test 
    public void testYourBean() 
    { 
     beanToTest.method(); 
     .... 
    } 
} 

编辑

对于配置类,你可以参考下面的代码。

@ContextConfiguration(classes=YourConfigClass.class, loader=AnnotationConfigContextLoader.class) 
public class YourTest extends AbstractJUnit4SpringContextTests 
{ 
    @Autowired 
    private YourBean beanToTest; 

    @Test 
    public void testYourBean() 
    { 
     beanToTest.method(); 
     .... 
    } 
} 
+0

在这里有一个问题,你是否在现实世界的项目中使用xml配置? –

+1

是的,我正在使用的项目仍在使用xml配置并编写像我所回答的单元测试类。顺便说一句,你可以参考[链接](http://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/),如果你是使用配置类。 – Alex

您可以轻松地将@Autowired属性为@Autowired构造。检查这个例子:

@Component 
public class SomeClass { 
    @Autowired 
    private SomeDependency someDependency; 

    public ... doSomething(...) { 
     ... 
    } 
} 

可以转化为

@Component 
public class SomeClass { 

    private SomeDependency someDependency; 

    @Autowired 
    public SomeClass(SomeDependency someDependency) { 
     this.someDependency = someDependency; 
    } 

    public ... doSomething(...) { 
     ... 
    } 
} 

其实是优选的这种注射方法,因为你的对象有所有需要构造完成时的依赖关系。在第一种方法中,您需要执行如下操作:

SomeClass someClass = new SomeClass(); 
someClass.setSomeDependency(someDependency); // <- you would need to add this 

此外还可能发生这种情况!

SomeClass someClass = new SomeClass(); 
someClass.methodThatUsesSomeDependency(); // <- NullPointerException since someDependency is not initialized! 

所以,通过使用构造函数注入你是安全的!您也可以通过设置你的依赖作为最后加一点额外的安全,使他们必须初始化时构造结束:

@Component 
public class SomeClass { 

    private final SomeDependency someDependency; 

    @Autowired 
    public SomeClass(SomeDependency someDependency) { 
     // Removing this line will cause a compile time error 
     this.someDependency = someDependency; 
    } 

    public ... doSomething(...) { 
     ... 
    } 
} 

所以,总结:将你的@Autowired注释构造,一切都将走精细。

一旦你与它的依赖作为参数单元测试构造它应该是微不足道的