好吧,让我谈谈我对此事的看法。这是域和api:
public class Contact implements Serializable {
private String firstName;
private String lastName;
private DateTime birthDate;
}
public interface ContactService {
List<String> getContacts();
}
@Service
public class ContactServiceImpl implements ContactService{
public List<String> getContacts() {
return new ArrayList<String>(asList("karl marx", " fridrih engels", " !!!"));
}
}
@RestController
public class ContactController {
public static final String QUALIFIER = "contactController";
public static final String MAPPING = "/contact";
@Autowired
private ContactService serviceInvoker;
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<String> findAll() {
List<String> strings = serviceInvoker.getContacts();
return new ResponseEntity<String>(Arrays.toString(strings.toArray()), HttpStatus.OK);
}
}
通过提供带有“调用端”上下文(在我的例子中为restcontroller)和“调用端”上下文(包含真实服务,而不是远程代理)的测试来测试这种配置是相当简单的。就像单体应用程序上下文一样。快速简便的方法。但在某些情况下还不够(例如,出于某些目的,您一方面自定义了 HttpInvokerProxyFactoryBean,另一方面自定义了 HttpInvokerServiceExporter)。
您可以覆盖 HttpInvokerProxyFactoryBean 类,使其成为 NonRemote。
首先,通过重写一些方法来修改 HttpInvokerServiceExporter;只需要将连接到 RemoteInvocation 和 RemoteInvocationResult 的方法公开。
public class OpenedHttpServiceExporter extends HttpInvokerServiceExporter {
@Override
public RemoteInvocation readRemoteInvocation(HttpServletRequest request) throws IOException, ClassNotFoundException {
return super.readRemoteInvocation(request);
}
.
.
.
etc...
}
让它成为 OpenedHttpServiceExporter。在测试/资源中创建 bean 描述符,将您在测试中需要的生产 bean 定义导入其中,并添加与原始 HttpInvokerServiceExporter 具有相同名称的 OpenedHttpServiceExporter bean - 它需要用于覆盖另一个。
测试上下文描述符opensServiceExporter.xml(没有beans元素):
<import resource="classpath:spring/serviceExporter.xml"/>
<bean id="contactExporter" class="pmp.testingremoting.service.OpenedHttpServiceExporter">
<property name="service" ref="contactServiceImpl"/>
<property name="serviceInterface" value="pmp.testingremoting.service.ContactService"/>
</bean>
并导入描述符:
<context:annotation-config/>
<context:component-scan base-package="pmp.testingremoting.service">
<context:exclude-filter type="annotation" expression="org.springframework.context.annotation.Configuration"/>
</context:component-scan>
<bean name="contactExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="contactServiceImpl"/>
<property name="serviceInterface" value="pmp.testingremoting.service.ContactService"/>
</bean>
扩展 HttpInvokerProxyFactoryBean,制作这个子类的 bean,自动将 HttpInvokerServiceExporter 字段插入其中。
覆盖公共对象调用(方法调用方法调用)
通过调用OpenedHttpServiceExporter.invoke(createRemoteInvocation(methodInvocation), exporter.getService());
它。
public class NonRemoteInvoker extends HttpInvokerProxyFactoryBean {
@Autowired
private OpenedHttpServiceExporter exporter;
public void setExporter(OpenedHttpServiceExporter exporter) {
this.exporter = exporter;
}
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
return exporter.invoke(createRemoteInvocation(methodInvocation), exporter.getService());
}
}
我们称这个新类为 NonRemoteInvoker。它必须只覆盖超类的一种方法,并将充当从“调用方”上下文到“被调用方”上下文的桥梁。
使用 NonRemoteInvoker 的实例创建“调用端”测试上下文描述符 (nonRemoteInvokerContext.xml)(同样,与原始 HttpInvokerProxyFactoryBean 具有相同的名称;也用于覆盖)。
<import resource="classpath:spring/webContext.xml"/>
<bean id="serviceInvoker" class="pmp.testingremoting.controller.NonRemoteInvoker">
<property name="serviceUrl" value="http://localhost:8080/remote/ContactService" />
<property name="serviceInterface" value="pmp.testingremoting.service.ContactService" />
</bean>
和 webContext.xml 是
<mvc:annotation-driven/>
<context:annotation-config/>
<context:component-scan base-package="pmp.testingremoting.controller">
<context:exclude-filter type="annotation" expression="org.springframework.context.annotation.Configuration"/>
</context:component-scan>
为“被调用方”创建测试配置。我使用了静态 @Configuration 类,只是将测试上下文描述符导入其中。
@Configuration
@ImportResource(locations = {
"classpath:openedServiceExporter.xml"
})
static class TunedBusinessConfig {
}
为“调用方”创建测试配置。我也是这样做的。
@Configuration
@ImportResource(locations = {
"classpath:nonRemoteInvokerContext.xml",
})
static class TunedRemoteInvokerConfig {
}
现在是测试班。它将通过@WebAppConfiguration 标记并具有这样的@ContextHierarchy,这将允许“调用方”上下文使用“调用方”上下文(调用-父,调用-子)。将 OpenedHttpServiceExporter 注入 NonRemoteInvoker 需要它。
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy({
@ContextConfiguration(classes = {
ContactControllerIntegrationTest.TunedBusinessConfig.class
}),
@ContextConfiguration(classes = {
ContactControllerIntegrationTest.TunedRemoteInvokerConfig.class
})
})
public class ContactControllerIntegrationTest {
.
.
.
}
这种方法使我不仅可以在测试中涵盖休息和服务层逻辑,还可以涵盖自定义 RemoteInvoker 的逻辑(我们称之为传输逻辑)。
这里有更多细节:
https ://github.com/PmPozitron/TestingRemoting/tree/lightVersion
我不确定这种方法是否正确,因此在适当的时候不会将答案标记为已接受。