如何用JUNIT5和Mockito模拟Spring的字段类型Resource?

发布于 2025-01-10 18:48:28 字数 1030 浏览 0 评论 0原文

我有一个从目录中读取 JSON 文件的类,但我无法模拟资源字段:

import org.springframework.core.io.Resource;

public class MyClass{

   
  @Value("classpath:file.json")
  private Resource resourceFile;

  public MyDTO getInfoFromJSONFile() {
    try {
        
     //Read file
    } catch (IOException e) {
      throw new MyException("General Error");
    }
  }

这是我的测试:

import org.springframework.core.io.Resource;

@ContextConfiguration({ "classpath:file.json" })
class MyClassTest{

    private MyClass subject;

    @Mock
    private Resource resourceFile;

    @BeforeEach
    void setUp() {
        this.subject = new MyClass();
        MockitoAnnotations.initMocks(this);
     }

    @Test
    @ParameterizedTest
    @ValueSource(strings = {"myParam"})
    void testReadInfoFromJsonFileSuccessfully(String param){
        MyDTO myDTO= subject.getInfoFromJSONFile(providerConfigId);
        Assertions.assertEquals(myDTO.getMyField(), "VALUE");
    }
}

资源文件字段从未使用模拟值初始化,我如何模拟这种类型的字段?

I have a class that reads JSON File from my directory, but I Could't mock the Resource field:

import org.springframework.core.io.Resource;

public class MyClass{

   
  @Value("classpath:file.json")
  private Resource resourceFile;

  public MyDTO getInfoFromJSONFile() {
    try {
        
     //Read file
    } catch (IOException e) {
      throw new MyException("General Error");
    }
  }

This my test:

import org.springframework.core.io.Resource;

@ContextConfiguration({ "classpath:file.json" })
class MyClassTest{

    private MyClass subject;

    @Mock
    private Resource resourceFile;

    @BeforeEach
    void setUp() {
        this.subject = new MyClass();
        MockitoAnnotations.initMocks(this);
     }

    @Test
    @ParameterizedTest
    @ValueSource(strings = {"myParam"})
    void testReadInfoFromJsonFileSuccessfully(String param){
        MyDTO myDTO= subject.getInfoFromJSONFile(providerConfigId);
        Assertions.assertEquals(myDTO.getMyField(), "VALUE");
    }
}

The field resourceFile never is initialized with a mock value, How can I mock this type of field ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨敛清荷 2025-01-17 18:48:28

Mockito @Mock 不执行 Spring 依赖注入机制。它只是创建一个模拟并将其分配给测试套件中的 resourceFile 字段。

有两种选择:

  1. 用构造函数注入替换字段注入并手动输入值。
public class MyClass{
  private Resource resourceFile;

  public MyClass(@Value("classpath:file.json") Resource resourceFile) {
    this.resourceFile = resourceFile;
  }
}

class MyClassTest{

    private MyClass subject;

    @Mock
    private Resource resourceFile;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
        this.subject = new MyClass(resourceFile);
     }
}
  1. 应用 @SpringBootTest 来运行 Spring Context 并继续 bean 生命周期。
@SpringBootTest
class MyClassTest{
    @Autowired
    private MyClass subject;
    ...
}

但在这种情况下,您将无法模拟 Resource。相反,您应该将包含所需内容的文件放入 test/resources 中。

Mockito @Mock does not perform Spring Dependency Injection mechanism. It just creates a mock and assigns it to the resourceFile field inside your test suite.

There are two options:

  1. Replace field injection with constructor injection and put the value manually.
public class MyClass{
  private Resource resourceFile;

  public MyClass(@Value("classpath:file.json") Resource resourceFile) {
    this.resourceFile = resourceFile;
  }
}

class MyClassTest{

    private MyClass subject;

    @Mock
    private Resource resourceFile;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
        this.subject = new MyClass(resourceFile);
     }
}
  1. Apply @SpringBootTest to run the Spring Context and proceed the bean lifecycle.
@SpringBootTest
class MyClassTest{
    @Autowired
    private MyClass subject;
    ...
}

Though in this case, you won't be able to mock Resource. Instead, you should put the file with required content to test/resources.

°如果伤别离去 2025-01-17 18:48:28

解决方案3:

@ExtendWith(MockitoExtension.class)
class MyClassTest{

@InjectMocks
private MyClass subject;

@Mock
private Resource resourceFile;
@Test
public void tesetMethod(){
    ClassLoader classLoader = getClass().getClassLoader();
    InputStream inputStream = classLoader.getResourceAsStream("file.json");
    Mockito.when(resource.getInputStream()).thenReturn(inputStream);

 
}

}

solution 3:

@ExtendWith(MockitoExtension.class)
class MyClassTest{

@InjectMocks
private MyClass subject;

@Mock
private Resource resourceFile;
@Test
public void tesetMethod(){
    ClassLoader classLoader = getClass().getClassLoader();
    InputStream inputStream = classLoader.getResourceAsStream("file.json");
    Mockito.when(resource.getInputStream()).thenReturn(inputStream);

 
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文