使用Mockito模拟自动连接的依赖项

hlswsv35  于 2022-11-08  发布在  其他
关注(0)|答案(2)|浏览(134)

我正在用Junit 5和Mockito 4为Spring项目编写单元测试。
我必须测试一个类,它通过构造函数接受2个对象,通过@Autowired接受另外2个对象。我需要模拟这4个对象,所以我在测试类中用@Mock注解了它们,然后用@InjectMocks注解了测试类。
我以为@InjectMocks会将我的4个模拟注入到myService中,但它只注入了构造函数传递的2个,而其他2个为空。
我正在寻找一个解决方案,它不意味着在测试的服务中的变化。
测试的类如下所示:

@Service
public class MyService {

private String key = "KEY";

@Autowired
private FirstApiWrapper firstApiWrapper;

@Autowired
private SecondApiWrapper secondApiWrapper;

private MyRepository myRepository;

private OtherService otherService;

@Autowired
public MyService(
    MyRepository myRepository,
    OtherService otherService
) {
    super();
    this.myRepository = myRepository;
    this.otherService = otherService;
}

我的测试类如下所示:

@ExtendWith(MockitoExtension.class)
public class MyServiceTest {

@Mock
MyRepository myRepository;

@Mock
OtherService otherService;

@Mock
FirstApiWrapper firstApiWrapper;

@Mock
SecondApiWrapper secondApiWrapper;

@InjectMocks
MyService myService;

我的代码有什么问题吗?非常感谢大家!
--我还尝试了基于this问题的一些方法:

@Mock
FirstApiWrapper firstApiWrapper;
@Mock
SecondApiWrapper secondApiWrapper;
@InjectMocks
MyService myService;

@BeforeEach
private void setUp() {

    myService = new MyService(
            Mockito.mock(MyRepository.class),
            Mockito.mock(OtherService.class)
    );
}

但是结果是完全一样的。而且,如果我删除存储库和服务示例,并试图只注入 Package 器,它仍然失败!

x7yiwoj4

x7yiwoj41#

我找到了一种方法来解决这个问题,而不需要重写现有的代码,通过将以下代码添加到测试类中:

@BeforeEach
private void setUp() {
    MockitoAnnotations.openMocks(this);
}

但我不确定这是否是一种“正确”的做法。

p3rjfoxz

p3rjfoxz2#

字段自动配置的一个问题是mockito不能注入任何东西。那么,如果你已经有了构造函数注入,为什么还要混合注入的风格呢?
重写类:

@Service
public class MyService {

private String key = "KEY";

private final MyRepository myRepository;

private final OtherService otherService;

private final FirstApiWrapper firstApiWrapper;

private final SecondApiWrapper secondApiWrapper;

@Autowired // if its the only constructor in the class, you can omit @Autowired, spring will be able to call it anyway. You can even use Lombok to generate this constructor for, so you won't need to even write this method
public MyService(
    MyRepository myRepository,
    OtherService otherService,
    FirstApiWrapper firstApiWrapper,
    SecondApiWrapper secondApiWrapper

) {

    this.myRepository = myRepository;
    this.otherService = otherService;
    this.firstApiWrapper = firstApiWrapper;
    this.secondApiWrapper = secondApiWrapper;
}

通过这种设计,您可以在测试中安全地使用@Mock/@InjectMocks注解
Mockito将创建类的示例并注入相关的模拟。

相关问题