Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 测试Axis 1.4 SOAP调用时有条件地模拟异常/返回值_Java_Spring_Exception_Junit_Axis - Fatal编程技术网

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

Java 测试Axis 1.4 SOAP调用时有条件地模拟异常/返回值,java,spring,exception,junit,axis,Java,Spring,Exception,Junit,Axis,为这个冗长的问题道歉 为了在我的单元测试中测试调用Axis1.4Web服务的业务逻辑,我目前正在使用Spring代理,它允许我设置异常并模拟返回值,如下所示 但是,我想知道是否有一种更干净的方法: 在我的JUnit应用程序上下文中,我将介绍以下建议: <bean id="testProxy" class="appl.service.TestProxyImpl" /> <bean id="testAdvice" class="org.springframework.aop.sup

为这个冗长的问题道歉

为了在我的单元测试中测试调用Axis1.4Web服务的业务逻辑,我目前正在使用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>
我简要地研究了EasyMock,但不确定如何创建一个模拟对象,该对象在某些时候拦截调用并返回异常或指定的返回值,但在其他时候使用正确的调用,因此我想知道是否有人对如何简化该调用有想法

注意,理想情况下,我希望避免重新布线
myBusinessObject
的属性

多谢各位

编辑:

我使用的是Spring2.5、JUnit3.8和Axis1.4

编辑2:


我使用这种方法来自动化集成测试,而不是简单的单元测试,因此,我非常欢迎您提出任何关于如何用基于库的东西来取代手工制作的解决方案的建议。

典型的分层开发应组织如下:

数据存取 业务逻辑 服务接口 这再次提醒您,在开发可重复的独立单元测试时,您的测试应该只针对其预期层和组件中的逻辑和功能。因此,在测试业务逻辑时,我根本不想进行实际的服务调用,我甚至不想进行数据访问调用,这就是为什么我们使用EasyMock之类的模拟框架

如果你不喜欢EasyMock,那么试着看看Mockito。它还有一些特性用于处理不太适合模拟的代码


我觉得奇怪的是,为了避免一点重新布线,你会费那么大的劲。这是非常值得重构的努力。

我同意分层开发方法(我也有一些独立的测试)。不重新布线的主要原因是自动化端到端测试,因为我已经被多次不做这样的测试所困扰(由于不同的团队在不同的组件上工作)。由于“myBusinessObject”包含许多不同的“myAxisProxy”对象,这种方法使测试许多不同场景(例如myAxisProxy1失败,但myAxisProxy1正常等)变得更容易,而无需重新连接“myBusinessObject”。这有意义吗?@beny23,很有意义,你需要端到端(集成)测试,但你也需要单元测试。如果您的工作环境是,其他团队的组件总是出现故障,那么当集成测试告诉您组件出现故障时,单元测试会告诉您组件正常!它们是打印组件的测试运行并证明代码中没有问题的重要工具。这都是关于CYA的。你给你的集成测试增加了相当大的复杂性,这似乎是因为你被别人的错误“咬”了?我喜欢这种方法,它很有意义,但正如我之前所说的,我认为在这一点上,当集成测试应该测试所有东西都正确部署到特定的端到端环境时,您将测试其他人组件中的功能。你明白其中的区别吗?这就好像其他组件开发人员在测试他们的组件方面没有做足够的工作,所以您实际上是在为他们测试他们的功能,因为您为此受到指责。这是一种反模式,更高层次的组件消费者因问题而受到指责。呵呵,告诉我,我们团队中流传的笑话是,如果互联网被破坏,人们会指责我们的组件。但说真的,有时我们会遇到测试资源稀缺的情况,不同的团队“忘记”测试整个应用程序,当业务逻辑中断时,会给我们留下支持电话,因为有人在回归测试中走捷径。所以,我将看看是否可以使用EasyMock和Mockito来取代我手工制作的解决方案。谢谢。
我们有时会遇到测试资源稀缺的情况,不同的团队“忘记”测试整个应用程序
代码的单元测试是一项开发任务,而不是QA任务。这不是“测试资源”的问题,而是“开发人员懒惰”和/或“管理层给出了不可能的截止日期”的问题<因为有人在回归测试中使用了快捷方式。若他们编写了正确的单元测试,那个么回归测试就像点击鼠标一样简单。但我离题了。相信我,你并不孤单。继续打好仗。
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();
 }