Springs @Autowiring 功能以及 Mocking

Springs @Autowiring functionality Along with Mocking

问题: 我有一个 class A

class A {

      @Autowired
      EdocumentDAO eDocumentDAO;

      public void createDocument(DocumentType docType)
      {
            String DocID= saveIndocRepo();//To be Mocked
            docType.setID(DocID);

            isSaved = eDocumentDAO.save()//Autowired

      }
      private String saveIndocRepo()
      {
          //Code to save in Repo in another platform and return the DOC_ID
      }


}

我的A_Testclass

@ContextConfiguration({ "classpath:test-beans.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
class A_test {

        A a = Mockito.spy(new A());

        Mockito.doReturn("DOC_ID").when(a).saveIndocRepo();
        a.createDocument(docType);      
}

要求: 我有方法 saveIndocRepo() 与外部服务交互并将文档保存在他们的仓库中。所以这个需要嘲笑一下。

createDocument() 中调用,模拟值应该是 returned.After 收到 DocID,其他文档详细信息保存到数据库中(为此我配置了 Derby In-内存数据库)。 EdocumentDAO 在由弹簧实例化的自动装配上工作。

问题: 当我尝试模拟方法(saveInDocRepo)时,它的模拟成功但自动装配失败。这导致 JUnit 失败。 当我删除模拟时,自动装配正在完美执行。

有没有我遗漏的东西。还是我的做法不对。 专家-请指教一个合适的解决方案。

您必须模拟接口而不是 Class 本身。 使用 Class 的 public 方法创建接口以模拟。

在上面的示例中,您正在监视 A,但 A 取决于 EdocumentDAO。你也必须模拟这个 Class。

@Mock
EdocumentDAO edocumentDAOMock;

或者,我最喜欢 Spring 的方式,因为您可以实现模拟行为:

@Bean
private EdocumentDAO getEdocumentDAOMock() {
    return mock(EdocumentDAO.class);
}

另外,由于你使用的是Spring,所以不能使用new A(),必须使用Spring来实例化一个Bean,否则autowired annotation将无法使用.

您可以使用 mockito 的 shorthand 注入而不依赖于 Spring 这个:

class ATest {
    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
    @Mock EdocumentDAO dao;
    @InjectMocks A a;

    @Test
    public void the_test() {
        doReturn("DOC_ID").when(dao).saveIndocRepo();
        a.createDocument(docType);
    }
}

注意这是伪代码,因为我现在不能使用 IDE

谢谢大家的帮助。

解决方案:

@ContextConfiguration({ "classpath:test-beans.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")

@Spy
@InjectMocks
A a = new A();

@Autowired
@Spy
EdocumentDAO eDocumentDAO;
class A_test {

        Mockito.doReturn("DOC_ID").when(a).saveIndocRepo();
        a.createDocument(docType);      
}

现在,当调用 createDocument() 方法时,saveInDocRepo() 被模拟为 return "DOC_ID" 并且 eDocumentDAO.save() 完美运行。 它的@Spy 用于部分模拟,挽救了这一天。