使用 Spring Boot 和 JUnit 从控制器类模拟存储库

Jav*_*per 6 junit mocking mockito powermock spring-boot-test

我正在为我的控制器类编写测试用例,它是一个 Spring Boot 应用程序,我只想为调用服务和存储库服务的控制器类编写测试用例。我正在使用 SpringBootTest,它用于为我的所有 bean 创建实例。我只想模拟数据库调用和外部 api 调用。

MyController {

    @Autowired
    MyService service;

    //Api call for getDetails
    service.getDetails();
}


MyService {

   @Autowired
   MyRepository repo;

}

MyControllertest {
    @Autowired
    MyController controller;

    @Mock
    MyRepository repoMock;

    @Before
    public void setup(){
        // intit mocks
    }

    @Test
    public void myTest(){
        when(repoMock.getDetails()).thenReturn(null);
        controller.getdetails();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行测试用例时,它没有使用模拟存储库,而是使用@AutowiredService 类中提到的存储库。

谁能解释一下如何从控制器类模拟存储库。

在这个博客中发布了很多问题,但没有得到任何答复。

pvp*_*ran 6

它没有使用您的模拟,因为您没有将这些模拟注入到您的控制器/服务类中。相反,你正在自动装配它。
正确的做法是

@RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {

    @InjectMocks
    MyController controller;
    .....

}
Run Code Online (Sandbox Code Playgroud)

更好的解决方案是摆脱字段注入并使用构造函数注入

例如在您的控制器和服务类中。您可以在构造函数上执行此操作,而不是在字段上使用@Autowired。例如

class MyService {

   private final MyRepository repo;

   @Autowired
   public MyService(final MyRepository repo) {
      this.repo = repo;
   }
}
Run Code Online (Sandbox Code Playgroud)

在 Controller 类中也是如此

class MyController {

    @Autowired
    private final MyService service;

    public MyController(final MyService service) {
         this.service = service
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做将帮助您在运行时轻松设置模拟。例如在你的测试课中你可以这样做

@RunWith(MockitoJUnitRunner.class)
public class MyControllertest {

    MyController controller;
    MyService service;

    @Mock
    MyRepository repoMock;


    @Before
    public void setup(){
        // init mocks
      service = new MyService(repoMock);
      controller = new MyController(service);
    }
  ..............
}
Run Code Online (Sandbox Code Playgroud)

是一篇关于字段注入的好文章


Ste*_*ner 0

一定不能打电话

MockitoAnnotations.initMocks(this);
Run Code Online (Sandbox Code Playgroud)

setUp方法中,因为SpringRunner已经初始化了模拟。通过调用,initMocks您可以将一个新对象分配给repoMock. 所有 Mockito 操作都when在新对象上执行,但 Spring 仍然MyRepository使用SpringRunner.