Mockito @InjectMocks - 模拟依赖注入

Mockito @InjectMocks 注释允许我们在注释类被嘲笑的对象中注入嘲笑的依赖性。当我们在我们想要嘲笑的类中有外部依赖性时,这是有用的。

莫克托 @InjectMocks

Mockito试图用三种方法之一注射嘲笑的成瘾,按照规定的顺序。

  1. 基于制造商的注射 - 当有一个为该类定义的制造商时,Mockito 会尝试使用最大的制造商 2 基于设置的方法 - 当没有定义的制造商时,Mockito 会尝试使用 setter 方法注入依赖 3 基于场 - 如果没有制造商或基于场的注射是可能的,那么mockito 会尝试将依赖物注入到该领域本身

如果只有一个匹配的模仿对象,那么mockito会将其注入到对象中. 如果有多个同一类的模仿对象,那么模仿对象名称被用来注入依赖。

Mock @InjectMocks 例子

让我们创建一些服务和类与依赖性,这样我们就可以看到Mockito依赖性注射的笑话在行动。

1package com.journaldev.injectmocksservices;
2
3public interface Service {
4
5    public boolean send(String msg);
6}
 1package com.journaldev.injectmocksservices;
 2
 3public class EmailService implements Service {
 4
 5    @Override
 6    public boolean send(String msg) {
 7    	System.out.println("Sending email");
 8    	return true;
 9    }
10
11}
 1package com.journaldev.injectmocksservices;
 2
 3public class SMSService implements Service {
 4
 5    @Override
 6    public boolean send(String msg) {
 7    	System.out.println("Sending SMS");
 8    	return true;
 9    }
10}

应用服务类与依赖性

 1package com.journaldev.injectmocksservices;
 2
 3//For Constructor Based @InjectMocks injection
 4public class AppServices {
 5
 6    private EmailService emailService;
 7    private SMSService smsService;
 8
 9    public AppServices(EmailService emailService, SMSService smsService) {
10    	this.emailService = emailService;
11    	this.smsService = smsService;
12    }
13
14    public boolean sendSMS(String msg) {
15    	return smsService.send(msg);
16    }
17
18    public boolean sendEmail(String msg) {
19    	return emailService.send(msg);
20    }
21}
 1package com.journaldev.injectmocksservices;
 2
 3//For Property Setter Based @InjectMocks injection
 4public class AppServices1 {
 5
 6    private EmailService emailService;
 7    private SMSService smsService;
 8
 9    public void setEmailService(EmailService emailService) {
10    	this.emailService = emailService;
11    }
12
13    public void setSmsService(SMSService smsService) {
14    	this.smsService = smsService;
15    }
16
17    public boolean sendSMS(String msg) {
18    	return smsService.send(msg);
19    }
20
21    public boolean sendEmail(String msg) {
22    	return emailService.send(msg);
23    }
24
25}
 1package com.journaldev.injectmocksservices;
 2
 3//For Field Based @InjectMocks injection
 4public class AppServices2 {
 5
 6    private EmailService emailService;
 7    private SMSService smsService;
 8
 9    public boolean sendSMS(String msg) {
10    	return smsService.send(msg);
11    }
12
13    public boolean sendEmail(String msg) {
14    	return emailService.send(msg);
15    }
16
17}

@InjectMocks 制造商注射示例

 1package com.journaldev.mockito.injectmocks;
 2
 3import static org.junit.jupiter.api.Assertions.*;
 4import static org.mockito.Mockito.*;
 5
 6import org.junit.jupiter.api.Test;
 7import org.mockito.InjectMocks;
 8import org.mockito.Mock;
 9
10import com.journaldev.injectmocksservices.AppServices;
11import com.journaldev.injectmocksservices.AppServices1;
12import com.journaldev.injectmocksservices.AppServices2;
13import com.journaldev.injectmocksservices.EmailService;
14import com.journaldev.injectmocksservices.SMSService;
15
16class MockitoInjectMocksExamples extends BaseTestCase {
17
18    @Mock EmailService emailService;
19    
20    @Mock SMSService smsService;
21    
22    @InjectMocks AppServices appServicesConstructorInjectionMock;
23    
24    @InjectMocks AppServices1 appServicesSetterInjectionMock;
25    
26    @InjectMocks AppServices2 appServicesFieldInjectionMock;
27    
28    @Test
29    void test_constructor_injection_mock() {
30    	when(appServicesConstructorInjectionMock.sendEmail("Email")).thenReturn(true);
31    	when(appServicesConstructorInjectionMock.sendSMS(anyString())).thenReturn(true);
32    	
33    	assertTrue(appServicesConstructorInjectionMock.sendEmail("Email"));
34    	assertFalse(appServicesConstructorInjectionMock.sendEmail("Unstubbed Email"));
35    	
36    	assertTrue(appServicesConstructorInjectionMock.sendSMS("SMS"));
37    	
38    }
39}

您是否注意到我的测试类正在扩展BaseTestCase。这是在测试之前初始化Mockito笑话,这里是该类的代码。

 1package com.journaldev.mockito.injectmocks;
 2
 3import org.junit.jupiter.api.BeforeEach;
 4import org.mockito.MockitoAnnotations;
 5
 6class BaseTestCase {
 7
 8    @BeforeEach
 9    void init_mocks() {
10    	MockitoAnnotations.initMocks(this);
11    }
12
13}

如果你不打电话MockitoAnnotations.initMocks(这);那么你会得到NullPointerException(/community/tutorials/java-lang-nullpointerexception)。同样,我正在使用 JUnit 5 来运行测试案例。如果你不熟悉它,请看看 JUnit 5 Tutorial

@InjectMocks 注射方法示例

 1@Test
 2void test_setter_injection_mock() {
 3    when(appServicesSetterInjectionMock.sendEmail("New Email")).thenReturn(true);
 4    when(appServicesSetterInjectionMock.sendSMS(anyString())).thenReturn(true);
 5    
 6    assertTrue(appServicesSetterInjectionMock.sendEmail("New Email"));
 7    assertFalse(appServicesSetterInjectionMock.sendEmail("Unstubbed Email"));
 8    
 9    assertTrue(appServicesSetterInjectionMock.sendSMS("SMS"));
10    
11}

@InjectMocks 基于领域的注射示例

 1@Test
 2void test_field_injection_mock() {
 3    when(appServicesFieldInjectionMock.sendEmail(anyString())).thenReturn(true);
 4    when(appServicesFieldInjectionMock.sendSMS(anyString())).thenReturn(true);
 5    
 6    assertTrue(appServicesFieldInjectionMock.sendEmail("Email"));
 7    assertTrue(appServicesFieldInjectionMock.sendEmail("New Email"));
 8    
 9    assertTrue(appServicesFieldInjectionMock.sendSMS("SMS"));
10    
11}

您可以从我们的 GitHub 存储库查看完整的代码和更多 Mockito 示例。

引用: API Doc

Published At
Categories with 技术
Tagged with
comments powered by Disqus