gpt4 book ai didi

java - JUnit/Mockito 测试用例在 Debug模式下通过但在运行模式下未通过

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:12:34 26 4
gpt4 key购买 nike

我正在使用以下方法来测试我项目中的配置文件对象更新。

import org.apache.commons.collections.MapUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.Callable;


@RunWith(MockitoJUnitRunner.class)
@PrepareForTest({TxUtils.class})
public class MonitoringProfileServicesImplTest extends MonitoringProfileServicesImpl {

private MutableDataObject mutableDataObject = Mockito.mock(MutableDataObject.class);

@Mock
private PersistenceContext<MutableDataObject> persistenceContext;

@Mock
PersistenceContextHelper persistenceContextHelper;

@Mock
MonitoringDao monitoringDao;

@InjectMocks
private MonitoringProfileServicesImpl service;

private BigInteger profileId;

private Map<String, BigInteger> attributeNameIdMap;

private Map<BigInteger, String> invAttributeNameIdMap;

ResponseBean responseBean = new ResponseBean();


@Before
public void setUp() {
Mockito.when(persistenceContextHelper.getLocalPersistenceContext()).thenReturn(persistenceContext);

profileId = BigInteger.valueOf(Long.valueOf(1L));

attributeNameIdMap = new HashMap<String, BigInteger>();
invAttributeNameIdMap = new HashMap<BigInteger, String>();
attributeNameIdMap.put("key", BigInteger.valueOf(1111L));
invAttributeNameIdMap = MapUtils.invertMap(attributeNameIdMap);
}


@Test

public void testXXXX() {
MonitoringProfile monitoringProfile = getDummyMonitoringProfileToBeCreated();

TransactionServicePALImpl transactionImpl = Mockito.mock(TransactionServicePALImpl.class);
Mockito.when(transactionImpl.getTM()).thenReturn(new TransactionManagerImplTest());


Mockito.when(mutableDataObject.getId()).thenReturn(BigInteger.valueOf(1000));
Mockito.when(mutableDataObject.getName()).thenReturn("Name");

Mockito.when(persistenceContext.getObjectById(Mockito.any(BigInteger.class))).thenReturn(mutableDataObject);
Mockito.when(monitoringDao.getAttributeIdsForObjectType(Mockito.any(BigInteger.class))).thenReturn(invAttributeNameIdMap);

TxUtils mock = PowerMockito.mock(TxUtils.class);
System.out.println("newresponseBean:::");



PowerMockito.when(mock.doTxRequired(new Callable<Object>() {
@Override
public Object call() throws Exception {

return this;
}

})).thenAnswer(new Answer<ResponseBean>() {
@Override
public ResponseBean answer(InvocationOnMock invocation) throws Throwable {

responseBean.setResultObj(monitoringProfile);
return responseBean;
}
});


ResponseBean newresponseBean = service.updateMonitoringProfile(monitoringProfile, BigInteger.valueOf(1000));
Assert.assertNotNull(newresponseBean);
Assert.assertNotNull(newresponseBean.getResultObj());
Assert.assertNull(newresponseBean.getErrorObj());
}

}

**在运行模式下,它在以下行失败

PowerMockito.when(mock.doTxRequired(new Callable<Object>().....

在 Debug模式下它工作正常。**

以下是服务方法代码;

public ResponseBean updateMonitoringProfile(@RequestBody MonitoringProfile profileToUpdate) {         
ResponseBean responseBean = TxUtils.doTxRequired(() -> {
ResponseBean response = new ResponseBean();
try {
PersistenceContext<MutableDataObject> localPersistenceContext = persistenceContextHelper.getLocalPersistenceContext();
MutableDataObject monitoringProfile = localPersistenceContext.getObjectById(profileToUpdate.getId());
ParamsBuilder paramsBuilder = populateProfileParameterValues(profileToUpdate, monitoringProfile).build();
localPersistenceContext.flush();
response.setResultObj(profileToUpdate);
} catch (NotUpdatedException notUpdatedEx) {
notUpdatedEx.printStackTrace();
}
return response;
});
return responseBean;
}

以下是我们在运行模式下运行时遇到的异常;

newresponseBean:::

org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.


at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:495)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)


Process finished with exit code -1

最佳答案

如果您的观察是真实的,并且在“调试”模式下单步执行测试用例时没有遇到这个问题;但是正常运行测试是可靠的,那肯定是某种时序问题。

我猜你在测试代码中有 synchronized 声明这一点表明你没有在此处显示的某些代码将使用多线程?!

鉴于我们无法重现这个问题;那是我建议您研究的部分。

除此之外:您得到的“模拟规范”部分错误。您希望指示您的环境何时使用一些参数调用静态方法 mock.doTxRequired(),然后应该发生这个或那个。

换句话说:在 when() 子句中提供 创建的对象是没有意义的。相反:模拟框架将在运行时检查运行时传递的参数是否等于您在 when() 子句中指定的对象!由于您没有在匿名内部类中实现 equals ... PowerMock 将永远不会确定模拟是使用该对象调用的。

换句话说:您可能想要使用某个对象,该对象等于将在运行时传递的对象;或者你使用像“any()”这样的参数匹配器(详见 here)。

仅作记录:如果您有可能考虑使用静态方法调用并避免使用PowerMock。

关于java - JUnit/Mockito 测试用例在 Debug模式下通过但在运行模式下未通过,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41758110/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com