Java Spring autowiring使JMockit在其他测试中保持模拟

Java Spring autowiring使JMockit在其他测试中保持模拟,java,spring,unit-testing,autowired,jmockit,Java,Spring,Unit Testing,Autowired,Jmockit,我试图单元测试一个类(比如说,“ClassUnderTest”)及其对特定库类的使用(我们称之为“Helper”)。因此,我将一个模拟的助手注入到被测类中,并使用期望值来检查问题 public class TestUseOfHelper { @Autowired ClassUnderTest classUnderTest; @Mocked HelperClass helper; [...] @Before public void setUp

我试图单元测试一个类(比如说,“ClassUnderTest”)及其对特定库类的使用(我们称之为“Helper”)。因此,我将一个模拟的助手注入到被测类中,并使用期望值来检查问题

 public class TestUseOfHelper {
     @Autowired ClassUnderTest classUnderTest;
     @Mocked    HelperClass    helper;
 [...]
     @Before
     public void setUp() throws Exception {
         Deencapsulation.setField(classUnderTest, "helper", helper);
     }
 [...]
     @Test
     public void test() {
         new Expectations() {{
             helper.doSomething(any);
         }};

         classUnderTest.useHelper();
    }
到目前为止,一切顺利

在其他测试中(相同的包,不同的文件),我正在测试ClassUnderTest的其他方面,我只想让Helper完成它的工作

 public class TestOtherQualities {
     @Autowired ClassUnderTest classUnderTest;
 [...]
     @Test
     public void test() {
        result = classUnderTest.processSomething();
        assertNonNull(result);
    }
这些测试也很有效

当我运行这套测试时,问题就出现了。现在,第二组失败了,显然是因为被模拟的辅助对象仍然存在

我假设完整套件是在同一个JVM中执行的,Spring创建了一个ClassUnderTest,按照它所说的注入模拟,但只是在下一个测试中重用相同的ClassUnderTest对象。我怎样把它们分开?如何为每个单独的测试文件获取“新鲜”对象?我没有得到什么/谷歌搜索

我尝试过在Expectations块中定义对象和使用@Tested/@Injected的多种方法,但都没有成功。顺便说一句,我避免在其他测试中嘲笑Helper,因为我需要它来完成它的任务。同样,ClassUnderTest自动连接一组其他对象,而这些对象又自动连接其他对象,因此模仿ClassUnderTest引用的所有对象是不切实际的


有什么见解吗,哦,魔法8球?(“稍后再试”是不可接受的。)

这是一个单元测试。因此,您根本不应该使用Spring来创建和自动关联对象。只要在每次需要时创建一个新的ClassUnderTest,并手动注入模拟依赖项:

@Before
public void setUp() {
    this.classUnderTest = new ClassUnderTest();
    Deencapsulation.setField(classUnderTest, "helper", mockHelper);
}

注意:我不知道JMockit,它可能有注释,甚至可以自动创建新的和注入模拟依赖项。我回答的要点是,对于单元测试来说,Spring应该是不存在的。这就是依赖项注入的主要优点:能够创建要测试的对象的实例,并且能够手动注入模拟依赖项。

这是一个单元测试。因此,您根本不应该使用Spring来创建和自动关联对象。只要在每次需要时创建一个新的ClassUnderTest,并手动注入模拟依赖项:

@Before
public void setUp() {
    this.classUnderTest = new ClassUnderTest();
    Deencapsulation.setField(classUnderTest, "helper", mockHelper);
}

注意:我不知道JMockit,它可能有注释,甚至可以自动创建新的和注入模拟依赖项。我回答的要点是,对于单元测试来说,Spring应该是不存在的。这就是依赖项注入的主要优点:能够创建要测试的对象的实例,并且能够手动注入模拟依赖项。

@DirtiesContext(classMode = AFTER_CLASS)

如果要在测试类之间重置应用程序上下文。

@DirtiesContext(classMode = AFTER_CLASS)

如果你想在测试类之间重置应用程序上下文。

这正是我想要的,但谷歌搜索并没有告诉我这一点!非常感谢!这正是我一直在寻找的,但谷歌搜索并没有向我透露这一点!非常感谢!考虑到这一点,理想情况下,每个类都应该在完全隔离的情况下进行测试。但是为所有东西实现注入有时是不切实际的(IMHO)。在我的例子中,我确实返回并开始从测试类中删除所有自动连接,并对所有内容使用mock。但是被测试的类执行一些文件和流操作,因此模拟很快就会变得比代码本身更复杂。我想听听其他人关于在单元测试中使用Spring和autowiring的情况。同样,我可以理解使用none的纯粹方法,但是在单元测试中使用Spring的实用性真的是一件坏事吗?毕竟,应用程序使用的是Spring,那么该连接不也应该进行测试吗?如果您意识到在测试中设置系统太难,那么您应该尝试更改它,因为存在太多依赖项:-)这一点,理想情况下,每个类都应该在完全隔离的情况下进行测试。但是为所有东西实现注入有时是不切实际的(IMHO)。在我的例子中,我确实返回并开始从测试类中删除所有自动连接,并对所有内容使用mock。但是被测试的类执行一些文件和流操作,因此模拟很快就会变得比代码本身更复杂。我想听听其他人关于在单元测试中使用Spring和autowiring的情况。同样,我可以理解使用none的纯粹方法,但是在单元测试中使用Spring的实用性真的是一件坏事吗?毕竟,应用程序正在使用Spring,那么该连接不也应该进行测试吗?如果您意识到设置测试中的系统太难,那么您应该尝试更改它,因为存在太多依赖项:-)