java - 如何确保没有实例的方法被调用?

标签 java unit-testing mocking

我有几个 small dieties在我的代码中,在测试时会引起痛苦。假设将小神打碎对这个练习来说太费力了。

通常的问题是我想测试 Foo 的方法 x() 但要创建 Foo 的实例,我需要定义 N (1 < N < 10) 个模拟实例,这些实例仅用于满足 Spring 的 @Autowire。在生产中,我必须确保这些字段是连线的,所以将它们设为可选不是一个选项。

我看到的可能的解决方案:

  1. 以某种方式告诉 Spring,某些 @Autowire 字段在测试期间是可选的
  2. 为被测代码不需要/不应需要的任何内容传递不可调用的模拟。

由于我不知道#1 的方法,我认为#2 是可行的方法。我更喜欢的是一个 bean 工厂,它返回一个代理,该代理为我没有定义的任何 bean 的任何方法调用抛出异常。

所以对于任何未知的 bean,它应该调用这个 create 方法:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MustNotCallMe {

    @SuppressWarnings( "unchecked" )
    public static <T> T create( final Class<T> type, final Class<?>... types ) {
        InvocationHandler handler = new InvocationHandler() {

            @Override
            public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable {

                if( "equals".equals( method.getName() ) && Object.class.equals( method.getDeclaringClass() ) ) {
                    return proxy == args[0];
                }

                throw new UnsupportedOperationException( "You must not call " + method );
            }
        };

        Class<?>[] allClasses = new Class<?>[ types.length + 1 ];
        allClasses[0] = type;
        System.arraycopy( types, 0, allClasses, 1, types.length );

        return (T) Proxy.newProxyInstance( MustNotCallMe.class.getClassLoader(), allClasses, handler );
    }
}

这样的东西存在吗?如果没有,我将如何在 Spring 3 单元测试中注入(inject)我自己的 bean 工厂?

编辑 我知道这个想法会让任何语言纯粹主义者感到不安。只有现实很少是纯粹的。如果这里有人愿意站出来为我们提供重构软件所需的资金和双手,我们很乐意听到。在那之前,无需太多手动工作即可解决问题的解决方案可以更好地解决我们的特定问题:-)

就是说,我所需要的只是一种创建 BeanFactory 的方法,它从不抛出 NoSuchBeanException 而是返回一个“不要叫我”代理。

最佳答案

我对这个领域相当陌生,但我认为 Spring 的整体理念是很容易交换部分以进行测试和环境中的其他更改。

从一个(认为他)理解这些概念但没有实现任何主要内容的人的角度来看,这有什么问题:每个 Autowiring 的部分都是一个接口(interface)。想象一个实现该接口(interface)的类,其中每个方法仅调用某种错误报告机制——它可以对所有方法都是相同的。创建这样一个类(手动)应该很快,不容易出错,现在你有了你的“模拟”。如果您有 10 个这样的对象,那么为每个对象创建这样一个类应该不会花那么长时间。

现在创建一个 spring 配置文件,传入给定测试集所需的这些模拟。如果有东西调用模拟类,它会吐出上述错误。当然,针对不同的测试环境,不同的配置可以包含不同的模拟。

我在这里错过了什么?

关于java - 如何确保没有实例的方法被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15137729/

相关文章:

java - 在 jdbc 应用程序中向前移动 rs.next()

java - 在 jPanel 上显示鼠标坐标

java - WEBSERVICES中编译Java WebService出错?

delphi - 如何在 Spring for Delphi 中使用带有 Autowiring 功能的模拟?

ios - 我应该重构以便能够在 XCTests 中使用模拟吗?

java - 如何验证 Selenium 中某个字段的大胆外观

python - 一段python代码如何判断它是否在unittest下运行

unit-testing - 在 go api 调用中测试

python - 如何模拟使用别名导入的函数?

unit-testing - 在单元测试中模拟我自己的服务