Spring 使用Junit和EasyMock使用自动连线表示法对类进行单元测试?

Spring 使用Junit和EasyMock使用自动连线表示法对类进行单元测试?,spring,unit-testing,dependency-injection,junit,mocking,Spring,Unit Testing,Dependency Injection,Junit,Mocking,我正在尝试为一个类编写一个单元测试,该类的几个字段标记为@Autowired。考虑到Spring自动解析这些字段的具体实现,我很难弄清楚如何在测试运行期间将模拟对象(通过EasyMock创建)作为依赖项插入。在类中使用@Autowired意味着该类中缺少setter。有没有一种方法可以让我在不在类中创建其他setter的情况下插入模拟对象 以下是我试图实现的一个示例: public类SomeClassUnderTest实现SomeOtherClass{ @自动连线 私人某物某物某物; @自动连线

我正在尝试为一个类编写一个单元测试,该类的几个字段标记为
@Autowired
。考虑到Spring自动解析这些字段的具体实现,我很难弄清楚如何在测试运行期间将模拟对象(通过EasyMock创建)作为依赖项插入。在类中使用
@Autowired
意味着该类中缺少setter。有没有一种方法可以让我在不在类中创建其他setter的情况下插入模拟对象

以下是我试图实现的一个示例:

public类SomeClassUnderTest实现SomeOtherClass{
@自动连线
私人某物某物某物;
@自动连线
私有SomeOtherType SomeOtherType;
@凌驾
public SomeReturnType someMethodIWouldLikeToTest(){
//使用someType和someOtherType并返回SomeReturnType
}
}
以下是我在碰壁之前如何设计我的测试类:

公共类MyTestClassForSomeClassUnderTest{
私人某物某物某物;
私有SomeOtherType SomeOtherType;
@以前
公共void testSetUp(){
SomeClassUnderTest someClassToTest=新建SomeClassUnderTest();
someType=EasyMock.createMock(someType.class);
someOtherType=EasyMock.createMock(someOtherType.class);
//如何设置依赖项????
}
@试验
public void TestSomeMethodIWouldLikeToTest(){
//??????
} 
}
朝着正确的方向推动会很好


谢谢

您可以使用,例如


有些人会争辩说,无论如何,最好在类中添加一个包可见的setter方法,仅由测试使用。或者,使用自动连接的构造函数,而不是自动连接的字段,并将测试依赖项注入其中。

尽管可以通过反射设置这些字段,但这样做会阻止开发工具找到这些字段的用法,并且使您将来重构
SomeClassToTest
变得更加困难

最好为这些字段添加公共设置器,并将
@Autowired
注释放在这些字段上。这不仅可以避免反射,还可以澄清类的外部接口,并确保单元测试只使用此接口。我看到
SomeClassToTest
已经实现了
SomeOtherClass
接口,并且我假设
SomeClassToTest
的客户端只使用这个接口,因此将
SomeClassToTest
上的setter公开几乎没有危险


更好的是,使用构造函数注入并使字段成为最终字段。您仍然可以在构造函数参数上使用
@Autowired

我不推荐已被接受的答案,即您自己使用反射(没有模拟框架)

由于EasyMock的3.2版,您可以使用注释来定义mock并将它们注入到被测试的类中。EasyMock的官方文档中有关于如何操作的完整说明:

以下是来自上述站点的一个示例:

import static org.easymock.EasyMock.*;
import org.easymock.EasyMockRunner;
import org.easymock.TestSubject;
import org.easymock.Mock;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EasyMockRunner.class)
public class ExampleTest {

  @TestSubject
  private ClassUnderTest classUnderTest = new ClassUnderTest(); // 2

  @Mock
  private Collaborator mock; // 1

  @Test
  public void testRemoveNonExistingDocument() {
    replay(mock);
    classUnderTest.removeDocument("Does not exist");
  }
}

EasyMock从3.2版开始就支持类似于Mockito的注释,用于模拟注入。请看我的答案。否决这个现在不应该被接受的答案(或者应该更新)。正如@krm所说,应该使用
@TestSubject
@Mock
注释。
import static org.easymock.EasyMock.*;
import org.easymock.EasyMockRunner;
import org.easymock.TestSubject;
import org.easymock.Mock;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EasyMockRunner.class)
public class ExampleTest {

  @TestSubject
  private ClassUnderTest classUnderTest = new ClassUnderTest(); // 2

  @Mock
  private Collaborator mock; // 1

  @Test
  public void testRemoveNonExistingDocument() {
    replay(mock);
    classUnderTest.removeDocument("Does not exist");
  }
}