Mockito @InjectMocks –模拟依赖注入
时间:2020-02-23 14:40:44 来源:igfitidea点击:
Mockito @InjectMocks批注允许我们将模拟的依赖项注入带注释的类模拟对象中。
当我们要模拟的类中具有外部依赖项时,这很有用。
我们可以使用@Mock或者@Spy批注指定要注入的模拟对象。
Mockito @InjectMocks
Mockito尝试使用三种方法之一以指定的顺序注入模拟的依赖项。
基于构造函数的注入–当为类定义了构造函数时,Mockito尝试使用最大的构造函数注入依赖项。
基于Setter方法-当未定义构造函数时,Mockito尝试使用setter方法注入依赖项。
基于字段的–如果没有构造函数或者基于字段的注入可能,那么Mockito尝试将依赖项注入字段本身。
如果只有一个匹配的模拟对象,则模拟将把它注入到对象中。
如果同一类的模拟对象不止一个,则使用模拟对象名称来注入依赖项。
模拟@InjectMocks示例
让我们创建一些具有依赖项的服务和类,以便我们可以看到Mockito依赖项注入了模拟。
服务等级
package com.theitroad.comjectmocksservices; public interface Service { public boolean send(String msg); }
package com.theitroad.comjectmocksservices; public class EmailService implements Service { @Override public boolean send(String msg) { System.out.println("Sending email"); return true; } }
package com.theitroad.comjectmocksservices; public class SMSService implements Service { @Override public boolean send(String msg) { System.out.println("Sending SMS"); return true; } }
具有依赖关系的App Service类
package com.theitroad.comjectmocksservices; //For Constructor Based @InjectMocks injection public class AppServices { private EmailService emailService; private SMSService smsService; public AppServices(EmailService emailService, SMSService smsService) { this.emailService = emailService; this.smsService = smsService; } public boolean sendSMS(String msg) { return smsService.send(msg); } public boolean sendEmail(String msg) { return emailService.send(msg); } }
package com.theitroad.comjectmocksservices; //For Property Setter Based @InjectMocks injection public class AppServices1 { private EmailService emailService; private SMSService smsService; public void setEmailService(EmailService emailService) { this.emailService = emailService; } public void setSmsService(SMSService smsService) { this.smsService = smsService; } public boolean sendSMS(String msg) { return smsService.send(msg); } public boolean sendEmail(String msg) { return emailService.send(msg); } }
package com.theitroad.comjectmocksservices; //For Field Based @InjectMocks injection public class AppServices2 { private EmailService emailService; private SMSService smsService; public boolean sendSMS(String msg) { return smsService.send(msg); } public boolean sendEmail(String msg) { return emailService.send(msg); } }
@InjectMocks构造函数注入示例
package com.theitroad.mockito.injectmocks; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import com.theitroad.comjectmocksservices.AppServices; import com.theitroad.comjectmocksservices.AppServices1; import com.theitroad.comjectmocksservices.AppServices2; import com.theitroad.comjectmocksservices.EmailService; import com.theitroad.comjectmocksservices.SMSService; class MockitoInjectMocksExamples extends BaseTestCase { @Mock EmailService emailService; @Mock SMSService smsService; @InjectMocks AppServices appServicesConstructorInjectionMock; @InjectMocks AppServices1 appServicesSetterInjectionMock; @InjectMocks AppServices2 appServicesFieldInjectionMock; @Test void test_constructor_injection_mock() { when(appServicesConstructorInjectionMock.sendEmail("Email")).thenReturn(true); when(appServicesConstructorInjectionMock.sendSMS(anyString())).thenReturn(true); assertTrue(appServicesConstructorInjectionMock.sendEmail("Email")); assertFalse(appServicesConstructorInjectionMock.sendEmail("Unstubbed Email")); assertTrue(appServicesConstructorInjectionMock.sendSMS("SMS")); } }
您是否注意到我的测试类正在扩展BaseTestCase
。
这是在测试之前初始化Mockito模拟,这是该类的代码。
package com.theitroad.mockito.injectmocks; import org.junit.jupiter.api.BeforeEach; import org.mockito.MockitoAnnotations; class BaseTestCase { @BeforeEach void init_mocks() { MockitoAnnotations.initMocks(this); } }
如果您不调用MockitoAnnotations.initMocks(this);
,则将获得NullPointerException
。
另外,我正在使用JUnit 5运行测试用例。
@InjectMocks设置器方法注入示例
@Test void test_setter_injection_mock() { when(appServicesSetterInjectionMock.sendEmail("New Email")).thenReturn(true); when(appServicesSetterInjectionMock.sendSMS(anyString())).thenReturn(true); assertTrue(appServicesSetterInjectionMock.sendEmail("New Email")); assertFalse(appServicesSetterInjectionMock.sendEmail("Unstubbed Email")); assertTrue(appServicesSetterInjectionMock.sendSMS("SMS")); }
@InjectMocks基于字段的注入示例
@Test void test_field_injection_mock() { when(appServicesFieldInjectionMock.sendEmail(anyString())).thenReturn(true); when(appServicesFieldInjectionMock.sendSMS(anyString())).thenReturn(true); assertTrue(appServicesFieldInjectionMock.sendEmail("Email")); assertTrue(appServicesFieldInjectionMock.sendEmail("New Email")); assertTrue(appServicesFieldInjectionMock.sendSMS("SMS")); }