在Junit WebMvcTest中如何访问一个RestController中的字段(或其getter和setter)?

huangapple go评论63阅读模式
英文:

How to access a filed(or its getter and setter) in a RestController in Junit WebMvcTest?

问题

Here is the translated content you requested:

目前,我正在使用Junit和Mockito为Spring Boot应用程序编写单元测试。我最近遇到的问题是,我们有一个RestController类,其中包含一些字段。

其中一些字段是通过构造函数注入的,可以进行模拟。

但我有一个私有字段,只能使用setter方法进行初始化。

让我们看一下代码:

@RequestMapping("/api/directory")
public class DirectoryController {
     private final DirectoryService service;
     private ScheduledFuture future;

     public ScheduledFuture getFuture() {
        return future;
    }

    public void setFuture(ScheduledFuture future) {
        this.future = future;
    }

    public DirectoryController (DirectoryService service) {
        this.service = service;
    }

    @GetMapping(value = "/sync")
    public String sync(){
       if(getFuture() == null) throw new RuntimeException();

       // 进行一些工作

    }
}

在这里,“ScheduledFuture future”应该使用其setter方法进行初始化。
现在,我无法为这个类中的sync()编写适当的WebMvcTest(在其中使用future字段)。因为future为空,除非我以某种方式初始化它,否则该方法将引发异常。

但我不知道该怎么做。

任何帮助将不胜感激。

英文:

Currently I'm writing unit tests for a spring boot application using Junit and Mockito. The problem I've encountered recently is that we have a RestController class which has some fields.

some of the fields are injected thorough Constructor and can be mocked.

but I have a private field which is not initialize using constructor and can be initialize only using setter method.

let's have a look at the code :

@RequestMapping("/api/directory")
public class DirectoryController {
     private final DirectoryService service;
     private ScheduledFuture future;

     public ScheduledFuture getFuture() {
        return future;
    }

    public void setFuture(ScheduledFuture future) {
        this.future = future;
    }

    public DirectoryController (DirectoryService service) {
        this.service = service;
    }


    @GetMapping(value = "/sync")
    public String sync(){
       if(getFuture() == null) throw new RuntimeException();

       // do some work

    }
  
}

Here "ScheduledFuture future" should be initilize using its setter method.
Now, I Cannot write a proper WebMvcTest for a sync() in this class(in which we use future field). because future is null and the method will throw an exception unless I initilize it somehow.

but I don't know how to do that.

Any help will be appreciated.

答案1

得分: 0

什么都不会阻止你手动调用setter方法。

让我们假设你有以下测试代码:

@WebMvcTest(DirectoryController.class)
class YourTest{
    @Autowired
    private MockMvc mockMvc;
    @Test
    void testSync() throws Exception{
        mockMvc
            .perform(get("/api/directory/sync"))
            .andExpect(status().isOk());
        //一些其他检查
    }
}

你可以只需自动装配控制器,创建你的模拟对象,然后在发出请求之前调用setter方法:

@WebMvcTest(DirectoryController.class)
class YourTest{
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private DirectoryController directoryController;//控制器已自动装配
    @Test
    void testSync() throws Exception{
        ScheduledFuture future = createYourMockObject();
        directoryController.setFuture(future);//这里
        mockMvc
            .perform(get("/api/directory/sync"))
            .andExpect(status().isOk());
        //一些其他检查
    }
}
英文:

Nothing stops you from calling the setter manually.

Let's assume you have a test like the following:

@WebMvcTest(DirectoryController.class)
class YourTest{
    @Autowired
    private MockMvc mockMvc;
    @Test
    void testSync() throws Exception{
        mockMvc
            .perform(get("/api/directory/sync"))
            .andExpect(status().isOK());
        //some other checks
    }

}

You can just autowire the controller, create your mock object and then call the setter before making the request:

@WebMvcTest(DirectoryController.class)
class YourTest{
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private DirectoryController directoryController;//controller is autowired
    @Test
    void testSync() throws Exception{
        ScheduledFuture future = createYourMockObject();
        directoryController.setFuture(future);//HERE
        mockMvc
            .perform(get("/api/directory/sync"))
            .andExpect(status().isOK());
        //some other checks
    }

}

huangapple
  • 本文由 发表于 2023年5月17日 18:47:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76271267.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定