gpt4 book ai didi

java - 测试 Axis 1.4 SOAP 调用时有条件地模拟异常/返回值

转载 作者:行者123 更新时间:2023-11-30 09:46:03 26 4
gpt4 key购买 nike

为冗长的问题道歉......

为了在我的单元测试中测试调用 Axis 1.4 Web 服务的业务逻辑,我目前正在使用 Spring 代理,它允许我按照以下设置异常和模拟返回值。

但是,我想知道是否有更简洁的方法:

在我的 JUnit 应用程序上下文中,我介绍了以下建议:

<bean id="testProxy" class="appl.service.TestProxyImpl" />
<bean id="testAdvice" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg index="0" ref="testProxy"/>
<constructor-arg index="1" value="appl.service.ITestProxy"/>
</bean>

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="myAxisProxy"/>
<property name="interceptorNames" value="testAdvice"/>
</bean>

TestProxyImpl类如下(需要看接口(interface)的告诉我):

public class TestProxyImpl 
extends DelegatingIntroductionInterceptor
implements ITestProxy {

private Map<String, Integer> calls = new HashMap<String, Integer>();
private Map<String, Throwable[]> exceptions = new HashMap<String, Throwable[]>();
private Map<String, Object> returnValues = new HashMap<String, Object>();
private Map<String, Object[]> lastParams = new HashMap<String, Object[]>();

public int getCalls(String methodName) {
Integer noCalls = calls.get(methodName);
if (noCalls == null) {
return 0;
}
return noCalls;
}

public void resetCalls() {
calls.clear();
returnValues.clear();
exceptions.clear();
lastParams.clear();
}

public void addExceptions(String method, Throwable... exceptions) {
this.exceptions.put(method, exceptions);
}

public void addReturnValue(String method, Object result) {
returnValues.put(method, result);
}

@SuppressWarnings("unchecked")
public <T> T getLastParameter(String method, Class<? extends T> paramClass) {
Object[] args = lastParams.get(method);
if (args != null) {
for (Object arg : args) {
if (arg != null) {
if (paramClass.isAssignableFrom(arg.getClass())) {
return (T)arg;
}
}
}
}
return null;
}

@Override
protected Object doProceed(MethodInvocation mi) throws Throwable {
String methodName = mi.getMethod().getName();
int noCalls;
synchronized (calls) {
noCalls = getCalls(methodName);
calls.put(methodName, noCalls + 1);
}
Object[] args = mi.getArguments();
synchronized (lastParams) {
lastParams.put(methodName, args);
}
if (exceptions.containsKey(methodName)) {
Throwable[] exceptionArray = exceptions.get(methodName);
if (exceptionArray != null) {
Throwable e = exceptionArray[noCalls % exceptionArray.length];
if (e != null) {
throw e;
}
}
}
if (returnValues.containsKey(methodName)) {
return returnValues.get(methodName);
}
return super.doProceed(mi);
}
}

这允许我使用以下单元测试:

protected void onSetUp() throws Exception {
super.onSetUp();

// testProxy is autowired into the unit test class
testProxy.resetCalls();
}

public void testSuccess() throws Exception {

// myBusinessObject is autowired into the unit test class
// myAxisProxy is injected into myBusinessObject in the spring context
// myBusinessObject calls myAxisProxy.myMethod(MyRequestObject) internally
myBusinessObject.doSomething();

// check that myAxisProxy has been called the correct times
// with the correct parameters
assertEquals(1, testProxy.getCalls("myMethod"));
assertEquals(
"foo",
testProxy.getLastParameter(
"myMethod",
MyRequestObject.class).getMyField());
}

public void testWithoutCallingProxy() throws Exception {

testProxy.addReturnValue("myMethod", createTestReturnValues());

myBusinessObject.doSomething();

// check that the response is as expected
}

public void testWithException() throws Exception {
testProxy.addException(
"myMethod",
AxisFault.makeFault(new ConnectException("test")),
null);

// this would check that the first call results in a ConnectException
// simulating a network error, but myBusinessObject retries
// and goes through to the service on the second call.
myBusinessObject.doSomething();
}

我已经简要研究了 EasyMock,但不确定我如何能够创建一个模拟对象来拦截调用并在某些时候返回异常或指定的返回值,但在其他时候使用正确的调用次,所以想知道是否有人对如何简化这一点有想法。

请注意,理想情况下,我想避免重新连接 myBusinessObject 的属性。

谢谢。

编辑:

我正在使用 Spring 2.5、JUnit 3.8 和 Axis 1.4

编辑2:

我正在使用这种方法来自动化集成测试,而不是简单的单元测试,所以我非常欢迎任何关于如何用基于库的东西替换手工解决方案的建议。

最佳答案

典型的分层开发应该像下面这样组织:

Data Access

Business Logic

Service Interface

这再次提醒您,在开发可重复的独立单元测试时,您的测试应该仅针对其预期层和组件中的逻辑和功能。因此,在测试业务逻辑时,我根本不想进行实际的服务调用,我什至也不想进行数据访问调用,这就是我们使用 EasyMock 等 Mocking 框架的原因。

如果您不喜欢 EasyMock,请尝试查看 Mockito。它具有更多功能来处理不太适合模拟的代码。

而且我觉得很奇怪,你会费那么大的劲来避免一点重新布线。重构工作非常值得。

关于java - 测试 Axis 1.4 SOAP 调用时有条件地模拟异常/返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7332510/

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