如何模拟在java中使用注入对象进行单元测试的私有方法?
为了测试我的如何模拟在java中使用注入对象进行单元测试的私有方法?,java,unit-testing,junit,testng,powermockito,Java,Unit Testing,Junit,Testng,Powermockito,为了测试我的DedupServiceWrapperImpl类,我需要模拟到私有方法“isDedupEnabled”和“isNew”。这是正在测试的类: public class DedupServiceWrapperImpl implements DedupServiceWrapper { @Inject private DedupService dedupService; @Inject private EventTypeService eventTypeS
DedupServiceWrapperImpl
类,我需要模拟到私有方法“isDedupEnabled”和“isNew”。这是正在测试的类:
public class DedupServiceWrapperImpl implements DedupServiceWrapper {
@Inject
private DedupService dedupService;
@Inject
private EventTypeService eventTypeService;
@Inject
private MessageLogService messageLogService;
private static final Logger logger = LoggerFactory.getLogger(DedupServiceWrapperImpl.class);
public Message dedup(Message message) {
if (isDedupEnabled(eventTypeName)) {
System.out.println("Dedup is enabled.");
if (isNew(digest)) {
System.out.println("it is new");
} else {
System.out.println("is not new");
}
} else {
System.out.println("Dedup is not Enabled");
}
}
private boolean isNew(Digest digest) {
return !dedupService.checkIfExists(digest.getDigest());
}
private boolean isDedupEnabled(String eventTypeName) {
boolean result = false;
try {
logger.info("Fetching eventType:{} to see if dedup is enabled on it.", eventTypeName);
EventType eventType = eventTypeService.findByName(eventTypeName);
if (eventType.isDedupEnabled()) {
result = true;
}
} catch (NotFoundException nfe) {
logger.warn("EventType '{}' not found!", eventTypeName);
}
return result;
}
}
这是我的单元测试课:
import com.sun.org.apache.bcel.internal.classfile.Method;
import com.tosan.chapar.core.exception.NotFoundException;
import com.tosan.chapar.core.service.DedupService;
import com.tosan.chapar.core.service.MessageLogService;
import com.tosan.chapar.ivr.service.DedupServiceWrapper;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.messaging.MessageHeaders;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
//import org.junit.Test;
import org.springframework.messaging.Message;
import static org.junit.runner.Request.method;
import static org.mockito.Mockito.*;
import static org.testng.Assert.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest(DedupServiceWrapperImpl.class)
public class DedupServiceWrapperImpl_DedupUTest {
private static final String payload = "Hello UTest.";
private Message inputMessage;
private MessageHeaders messageHeaders;
//@Mock
//private DedupService dedupService;
//@InjectMocks
private DedupServiceWrapper dedupServiceWrapper;
@Test
public void testName() throws Exception {
}
@SuppressWarnings("unchecked")
@BeforeMethod
public void setupMocks() throws NotFoundException {
MessageLogService messageLogService = mock(MessageLogService.class);
/*digest = mock(Digest.class);
eventType = mock(EventType.class);
eventType.setName("modern_chaparbo_free");
eventType.setDedupEnabled(true);
eventTypeService = mock(EventTypeServiceImpl.class);
when(eventTypeService.findByName("modern_chaparbo_free")).thenReturn(eventType);*/
messageHeaders = mock(MessageHeaders.class);
when(messageHeaders.get("eventTypeName")).thenReturn("modern_chaparbo_free");
when(messageHeaders.get("recipient")).thenReturn("+982112345678");
when(messageHeaders.size()).thenReturn(2);
inputMessage = mock(Message.class);
when(inputMessage.getHeaders()).thenReturn(messageHeaders);
when(inputMessage.getPayload()).thenReturn(payload);
}
/**
* dedupEnabled is false
*/
@Test//(expected = RuntimeException.class)
public void dedup_Disablededup_dedupeIsNotDone() throws Exception{
//doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class))
DedupServiceWrapperImpl spy = PowerMockito.spy(new DedupServiceWrapperImpl());
//DedupServiceWrapper spy = mock(DedupServiceWrapperImpl.class);
PowerMockito.doReturn(false).when(spy, "isDedupEnabled", anyString(),);
//PowerMockito.verifyPrivate(spy, times(0)).invoke("isDedupEnabled", anyString());
//PowerMockito.when(spy, method(DedupServiceWrapperImpl.class, "isDedupEnabled", String.class)).withArguments(anyString()).thenReturn(false);
//PowerMockito.verifyPrivate(spy, times(2)).invoke("isDedupEnabled", anyString());
//PowerMockito.doReturn(false).when(spy, method(DedupServiceWrapperImpl.class, "isDedupEnabled", String.class)).withArguments(anyString());
/*DedupServiceWrapper truck = new DedupServiceWrapperImpl();
DedupServiceWrapper truckSpy = PowerMockito.spy(truck);
PowerMockito.doReturn(false).when(truckSpy,
"isDedupEnabled");*/
Message message = spy.dedup(inputMessage);
org.junit.Assert.assertEquals(inputMessage, message);
assertNotNull(message);
assertEquals(message, inputMessage);
}
}
我已经尝试了我的测试课上的所有样本,但它们不起作用,我让他们评论
我不能模拟两个私有方法-我如何才能做到这一点?为什么它不起作用
它抛出了这样的信息:
Method threw 'org.mockito.exceptions.misusing.WrongTypeOfReturnValue' exception. Cannot evaluate com.tosan.chapar.ivr.service.impl.DedupServiceWrapperImpl$$EnhancerByMockitoWithCGLIB$$9a511df1.toString()
可以使用PowerMock模拟私有方法,也可以研究使用Mockito间谍进行部分模拟 但大多数情况下,对这些技巧的需求是一个正在测试的有缺陷的设计。换句话说:相反,尝试修复难以测试的生产代码的症状。。。而是把时间花在使代码易于测试上 您将TestNG(
org.TestNG.annotations.*
)和JUnit(org.JUnit.runner.*
)混合在同一个类中,这是不允许的
如果要使用PowerMock和TestNG,则需要扩展
PowerMockTestCase
。查看文档:为什么要模拟私有方法?唯一可以调用它的是模拟对象中的其他方法。不清楚为什么要这样做。单元测试需要模拟依赖项,然后在CUT上调用方法。然后验证剪切是否以正确的方式运行-调用依赖项上的正确方法,返回给定的正确值。应该没有理由在CUT中模拟private
方法!我想测试“重复数据消除(消息)”方法,该方法调用私有方法“isDedupEnabled”和“isNew”。我想模拟这些私有方法。尽管这种做法听起来很糟糕(私有方法是一种实现细节),但我甚至不确定这是否可行-你想模拟你正在测试的对象?@m.mjn202不,你真的不想模拟私有方法<例如,调用eventTypeService.findByName(eventTypeName)
-因此,您可以使用stubeventTypeService.findByName
为给定测试内容的调用提供正确的值。我认为第二段比第一段更重要。但是您是否可以使用这些机制中的任何一种来模拟您尝试测试的对象?@OliverCharlesworth您可以是的。然而这是一件很奇怪的事…@GhostCat,谢谢你。。。我已经用edite my pom.xml解决了这个问题:|