Java 单元测试动态类负载

Java 单元测试动态类负载,java,unit-testing,dynamic,reflection,groovy,Java,Unit Testing,Dynamic,Reflection,Groovy,我有一个简单的Java动态工厂模式(实际上是groovy,但出于所有目的,我们可以假设它是Java),它接收一个操作,并通过从具有相应名称的属性文件中读取它来动态加载该特定操作的处理程序 该模式非常简单,只要有一个具有以下签名的基本方法: class ReflectionFactory implements BaseFactory { PropertyReader propertyReader public ReflectionFactory(PropertyReader rea

我有一个简单的Java动态工厂模式(实际上是groovy,但出于所有目的,我们可以假设它是Java),它接收一个操作,并通过从具有相应名称的属性文件中读取它来动态加载该特定操作的处理程序

该模式非常简单,只要有一个具有以下签名的基本方法:

class ReflectionFactory implements BaseFactory {

   PropertyReader propertyReader

   public ReflectionFactory(PropertyReader reader) {
      this.propertyReader = reader
   }

   Adapter resolveAdapter(String serviceName) {
    // TODO: Find service configuration in propertyReader and load via class loader
      return defaultAdapter
   }
}
该类中的功能尚未实现,我希望使用TDD实现它,也就是说,我希望创建一个测试,该测试将验证给定serviceName时,它是否将返回适当类型的类

将加载该类的代码类似于:

String className = propertyReader.getProperty(serviceName)
this.class.classLoader.loadClass(className, true, false)
在我看来,我需要“模拟”类加载器,但显然我不想引入注入类来取代这一行:

this.class.classLoader.loadClass(className, true, false)
有没有办法测试类加载器是否使用正确的参数调用?换句话说,有没有办法“模拟”或“替换”类加载器的调用

理想情况下,我可以做(伪代码)

因此,测试代码将类似于:

void testWhenResolveServiceAndClassPropertyDefinedInstansceIsCreated() {

  serviceName = "myService"
  when(propertyReader.getPropertyValue("myService")).thenReturn("com.mydomain.adapters.testAdapter")
  when(classLoader.loadClass("com.mydomain.adapters.testAdapter", true, false)).thenReturn(testDummy)

  def factory = new ReflectionFactory(propertyReader)
  def adapter = factory.resolveAdapter(serviceName)

  assertNotNull(adapter)
  verify(classloader).loadClass("com.mydomain.adapters.testAdapter", true, false)
}

我使用Mockito作为模拟框架,但任何模拟框架/解决方案都是受欢迎的

据我所知,我可以提出类似的建议(测试是在spock框架中编写的):


希望它能对您有所帮助。

在我尝试之前,您能否提供ReflectionFactory和test的完整示例实现(以及何时)?可能没有编译,也不能正常工作-只是想了解整个情况。实现正如我定义的,也就是说,功能还没有实现。看一下编辑好的问题,了解我想写的测试的详细信息。我会在UTC晚上试一试。这就是你想要的吗?
void testWhenResolveServiceAndClassPropertyDefinedInstansceIsCreated() {

  serviceName = "myService"
  when(propertyReader.getPropertyValue("myService")).thenReturn("com.mydomain.adapters.testAdapter")
  when(classLoader.loadClass("com.mydomain.adapters.testAdapter", true, false)).thenReturn(testDummy)

  def factory = new ReflectionFactory(propertyReader)
  def adapter = factory.resolveAdapter(serviceName)

  assertNotNull(adapter)
  verify(classloader).loadClass("com.mydomain.adapters.testAdapter", true, false)
}
@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')

import spock.lang.*

class Test extends Specification {
   def 'test'() {
      given:
      def propertyReader = GroovyMock(PropertyReader)
      def loader = GroovyMock(ClassLoader)        

      and:
      def serviceName = 'service'
      def serviceClass = 'service.class'
      def adapter = new Adapter()

      and:
      def factory = new ReflectionFactory()
      factory.propertyReader = propertyReader
      factory.loader = loader

      when:
      def ret = factory.resolveAdapter(serviceName)

      then:
      ret == adapter
      1 * propertyReader.findProperty(serviceName) >> serviceClass
      1 * loader.loadClass('service.class', true, false) >> adapter
   }
}

class ReflectionFactory {

   PropertyReader propertyReader
   ClassLoader loader = getClass().getClassLoader()

   Adapter resolveAdapter(String serviceName) {
      def cls = propertyReader.findProperty(serviceName)
      loader.loadClass(cls, true, false)
   }
}

class PropertyReader {
    String findProperty(String name) {
        //some logic here
    }
}

class Adapter {}