在静态对象和非静态对象上使用 InjectMock 和 MockBean

问题描述 投票:0回答:1

我有一个使用依赖项的服务类 -

我的服务

@Service
@ToString
public class MyService{

    Dependency dependency;

    public MyService(Dependency dependency) {
        System.out.println("started MyService constructor");
        this.dependency = dependency;
        System.out.println("ended MyService constructor with dependency = " + this.dependency);
    }

    public void myMethod() {
        System.out.println("printing in myMethod : " + dependency.someMethod());
    }

    public void setDependency(Dependency dependency) {
        this.dependency = dependency;
        System.out.println("called setter with dependency = " + this.dependency);
    }
}

依赖性

@Component
public class Dependency {
    public String someMethod() {
        return "calling dependency someMethod";
    }
}

我为 MyService 类编写了 2 个测试用例 -

@ExtendWith(SpringExtension.class)
class MyServiceTest {

    @InjectMocks
    MyService myService;

    @MockBean
    Dependency dependency;

    @BeforeEach
    void beforeEach() {
        System.out.println("beforeEach");
    }

    @Test
    void test1() {
        System.out.println("test1 start");
        when(dependency.someMethod()).thenReturn("calling mock dependency 1 someMethod");
        myService.myMethod();
        System.out.println("test1 end");
    }

    @Test
    void test2() {
        System.out.println("test2 start");
        when(dependency.someMethod()).thenReturn("calling mock dependency 2 someMethod");
        myService.myMethod();
        System.out.println("test2 end");
    }
}

我尝试在 MyServiceTest 中将 MyService 和依赖项设置为静态/非静态,并得到以下结果 -

  1. MyService 静态,依赖静态
    MyService 的构造函数以 dependency = null 运行
    第一次测试运行并失败
    调用 setDependency 并将依赖项设置为模拟对象
    第二次测试运行良好
  2. MyService 静态,依赖关系非静态
    MyService 的构造函数以 dependency = null 运行
    第一次测试运行并失败
    第二次测试运行但失败
  3. MyService 非静态,依赖静态
    MyService 的构造函数以 dependency = null 运行
    第一次测试运行并失败
    MyService 的构造函数以依赖项 = 某个模拟对象运行
    第二次测试运行良好
  4. MyService 非静态,依赖关系非静态
    MyService 的构造函数以 dependency = null 运行
    第一次测试运行并失败
    MyService 的构造函数以 dependency = null 运行
    第二次测试运行良好

有人可以帮助我理解这些行为吗?

java mockito junit5 springmockito
1个回答
0
投票

也许你可以通过

修复
@ExtendWith(SpringExtension.class)
class MyServiceTest {
    private MyService myService;

    @MockBean
    private Dependency dependency;

    @BeforeEach
    void beforeEach() {
        myService = new MyService(dependency);
    }
    ...
}

此外,您应该删除

setDependency(...)
中的
MyService
方法并将
dependency
定为最终方法。例如

public class MyService{
    private final Dependency dependency;

    public MyService(Dependency dependency) {
        this.dependency = dependency;
    }
    ...
}

就我个人而言,我避免同时使用

@MockBean
,因为它会导致许多问题(当您可能希望在测试之间共享应用程序上下文时,它会加载新的应用程序上下文)。在这种情况下,您可以愉快地使用
@Mock
而不是
@MockBean
,因为您没有与其他测试共享应用程序上下文(例如,您没有使用
@SpringBootTest

© www.soinside.com 2019 - 2024. All rights reserved.