技术开发 频道

通过服务模拟来简化SOA开发

    服务模拟

    此 SOA 开发流程的第三步是开发服务模拟——通过服务测试的模拟对象。这些服务模拟是实际服务提供程序的简单原型。

    Kent Beck 将模拟对象 描述为测试对象,该对象可以使用常量进行响应,从而实现开销大或复杂的资源的模仿版本。例如,模拟数据库是一个简单对象,但具有数据库的 API,可以接受一些已知的 SQL 字符串,并为每个字符串返回一组固定的结果。模拟对象允许您对组件进行测试,而不必依赖于外部资源。

    现在假定此外部资源是一个 SOA 服务。如果您的组件使用该服务,则测试此组件时也在测试该服务。如果服务工作不正常,或者不可用,则即使组件工作正常,测试也会失败。如果服务很慢(通过网络远程调用服务时就是这样),您的测试也会运行得很慢——这样就不能如您所愿频繁地运行测试了。而且,如果服务尚未实现,则根本就不能对您的组件进行测试。

    因此,一个不错的方法就是开发服务模拟,模拟对象是实际服务的简单仿真程序。服务具有与实际服务相同的 API;它会实现针对服务测试而开发的接口。服务模拟应该如何工作?它应该通过您已经开发的服务测试,这表明模拟真的和实际服务的工作方式一样。

    在某些情况下,服务模拟实际上比实际服务更适合用于进行测试工作。假定您的组件使用返回股票报价的服务。如果传入代码 IBM,您将获得什么样的结果呢?$50?$100?$150?具体取决于当前的股票价格,但这是测试的一个“鸡与蛋”问题。通过使用服务模拟,已硬编码的模拟将始终返回 $100,然后据此进行测试,与测试实际服务相比,这实际上更加可靠。

    谁开发服务模拟?提供程序团队(而非协调程序团队)应该开发服务模拟。服务模拟表示提供程序团队计划实际实现的内容的简单实现。如果相同的服务有多个提供程序团队,则他们必须进行协调,以产生一个他们都认可的模拟服务。

    示例服务模拟

    此示例服务模拟需要通过我前面编写的示例服务测试。因此,它的简单报价实现是一个 case 语句。如果服务只是一个传统 Java 对象(plain old Java object,POJO),则对应的模拟将为通用接口的特殊实现,如下所示:

    清单 1:作为通用接口的特殊实现的服务模拟

    public class StockQuoteMock implements StockQuoteService

    简单报价则将为 StockQuoteService 中声明的一个方法,并在 StockQuoteMock 实现如下方法:

    清单 2:在 StockQuoteService 中声明并在 StockQuoteMock 中实现的简单报价方法

public String getSimpleQuote(String symbol) throws InvalidSymbolException {
if (symbol == null) throw new InvalidSymbolException(symbol);
if (symbol.equals("IBM")) return "$100.00";
if (symbol.equals("MSFT")) return "$30.00";
if (symbol.equals("BOGUS")) throw new InvalidSymbolException(symbol);
throw new InvalidSymbolException(symbol);
}

    如果服务更复杂(如无状态会话 Bean 或 SOAP Web 服务),此 POJO 代码仍然可以作为更复杂的模拟实现的基础。在任何情况下,模拟实现肯定都不应该试图处理每个可能的股票代码或访问具有实时数据的数据库。模拟实现应该足以通过服务测试即可。

0
相关文章