Section 19.1. Simulation Service


19.1. Simulation Service

Canned, Double, Dummy, Fake, Masquerade, Mock, Service, Shunt, Sim, Simulation, Stub

Figure 19-1. Simulation Service


19.1.1. Developer Story

Dave is beginning to work on a new email application. Eventually, the server will need to expose a mail API, so the browser can query for recent messages and upload new ones. However, that will require email expertise, and Dave wants to focus on the user interface in the browser for now. Thus, he hardcodes the responses he'd like in a "fake" server-side service. This allows him to proceed with user-interface development while his colleague takes care of the real server implementation.

19.1.2. Problem

How can you develop the browser script in parallel with the services it uses?

19.1.3. Solution

Develop the browser application against "fake" web services that simulate the actual services used in production. A Simulation Service is typically a hardcoded response that ignores any input parameters. So instead of:

   $taxRate = calculateTaxRate($userId, $year);   print $taxRate; 

a Simulation Service would just say:

   print "0.1235"; 

It's also possible to do all this in a browser. If you use a library to perform Web Remoting (Chapter 6), you could make the implementation produce a hardcoded response, and ignore the server altogether.

In some cases, you might make the service more flexible; e.g., it can expose an operation to let the browser tell it what to output later on.

Simulation Service decouples the server and browser components of the application. Once the interface is defined, each can be developed in parallel. Moreover, this pattern paves the way for an agile process for building the application, based loosely on concepts such as Test-Driven Design (TDD) and lean manufacturing.

Mocks, Stubs, Simulations

A Simulation Service is a kind of "stub." In software testing, simple stubs are created to provide isolated tests. Instead of working with real components, the tested component works with simple stubs. Because the stubs are simple and stable, any test failures can then be attributed to the tested component. Furthermore, stubs will always yield the same result, so it's easier to automate the test.

It's important to distinguish between "mocks" and stubs, because the terms are often used interchangeably (http://www.softwareas.com/mocks-stubs-dependency-injection-and-xmlhttprequest). Like a stub, a "mock" simulates a real component. But for a mock, the simulation is only a by-product of its true purpose: to verify that it's used correctly. Before a test, the mock is told what calls the component will make on it. As soon as that sequence is violated, the mock will complain and the test will fail. There are several potential applications for mocks in Ajax; one of those involves mock Services. The browser could start a test by telling a mock XMLHttpRequest wrapper what calls will soon be made. Then, the wrapper will throw an exception if that call isn't actually made. "Mock Service" is too immature a concept to form a pattern at this stage, but it's something that might emerge as Ajax developers focus on testing techniques.


Conventional web development is usually a bottom-up approach: first comes the database, then the data layer to access it, then the business components on top of that, and finally the user interface. This sequence might seem like the most logical thing to do, given the dependency relationships involved. But the problem is that the user interface is really the whole point of the application, so there's a good argument for starting there instead. For a given feature, flesh out the user interface and use that work to drive the service interface. So instead of designing the server side first and forcing the browser script to work with whatever interface arises, let the needs of the browser script drive the interface design. Consequently, the service will not only contain the precise functionality required by the browser, but also expose it with the most suitable interface.

Starting development in the browser sounds like a good idea until you realize the browser depends on the service, which doesn't yet exist! That's where a Simulation Service comes in: it lets you define what the service offers, not how the service achieves it. As you develop the browser script, you'll continue to come across refinements to the servicean extra operation here, a different response format there. In each case, changing the Simulation Service is usually as simple as editing the hardcoded response. Once you're confident with the requirements for the Service, youor someone elsecan go build the real thing.

Another application is in Browser-Side Tests (see later in this chapter). When testing a browser component, it's important to test only the component itself, and not the services it depends on. Imagine you're testing a browser component that renders news arriving from an RSS web service. An automated test could then interrogate the DOM and run a bunch of assertions to ensure it was formatted correctly. But if the component uses the real service, the resulting DOM will reflect the news of the hour. A human could manually verify it, but automation wouldn't be possible. A hardcoded response would eliminate that problem, allowing the assertions to be consistent with the simulated RSS. Furthermore, there's no dependence on the real implementationno matter how complex the actual search algorithm, the rendering component will always be tested on its own merit.

19.1.4. Decisions

19.1.4.1. How will you switch between different services?

It's easy enough to create a Simulation Service, but how do you switch between the simulation and the real thing? And, how do you switch between different simulation services, since you might prefer one or the other for different tasks. Right now, there's no easy answer to that because there's no real support in the way of tools and libraries. Where the practice of Simulation Service is followed, most developers probably switch over to a real service in the most brute-force way possible: they edit the code. But doing so means there's a manual step involved in order to test or deploy. Here are a few ways to make the process more manageable:

  • Keep the JavaScript pointing at the same service URL, but have your server-side build tool (e.g., ant) decide what implementation resides there.

  • Build some configuration into the JavaScript to help it point to the correct service. This would be useful for an automated JavaScript-based test. You could even create a simple browser control to let the user choose which service is executed, which is helpful during development.

  • Instead of hosting JavaScript in a static file, dynamically generate it from the server, so that variable URLs can be set on the fly.

19.1.5. Code Example: Simulation Service

The Ajax Pattern Reader (http://ajaxify.com/run/reader/) runs against a couple of Cross-Domain Proxy (Chapter 10) services. They fetch information from the AjaxPatterns.org web site and return them in a format easily parsed by the browser. For development purposes, the Basic version (http://ajaxify.com/run/reader/) uses Simulation Service.

The first service produces a Plain-Text Message (Chapter 9) containing the patterns in a pipe-separated list. A hand-created simulation (http://ajaxify.com/run/reader/patternList.phtml) is used instead of fetching the page from AjaxPatterns.org, parsing the HTML, and reformatting it.

   Periodic Refresh|||One-Second Spotlight|||Slider 

For comparison, the real service outputs a list that looks similar, but is much longer, and, of course, not hardcoded (http://ajaxify.com/run/reader/logging/realService/patternList.phtml).

   Ajax Stub|||Browser-Side Cache|||Browser-Side Templating||| ... |||XML       Message|||XMLHttpRequest Call 

Similarly, there's a simulation of the summary service (http://ajaxify.com/run/reader/patternSummary.phtml?patternName=Slider), whose job is to produce an HTML Message summarizing a given pattern. The simulation includes some rudimentary logic to make the response vary according to the input:

   <?  $patternName = urlDecode($_GET["patternName"]); ?>     <h1><?= $patternName ?></h1>   <?  if ($patternName=="Periodic Refresh") { ?>       With periodic refresh, it's all about the timer.   <?  } else if ($patternName=="Slider") { ?>       <p>The slider slides from left to right.</p>       ...   <?  } else {       print ("Text goes here.");     }   ?> 

The output from the real service is in the same format (http://ajaxify.com/run/reader/logging/realService/patternSummary.phtml?patternName=Slider), but as with the list service, it's fetched from AjaxPatterns.org in real-time.

19.1.6. Related Patterns

19.1.6.1. Service Test

A Simulation Service is a good starting point for a real service. You might begin developing a Service Test (see later) against a Simulation Service, then evolve both into a real service and test.

19.1.7. Want to Know More?

  • In Lean IT Processes terminology, the Simulation Service pattern facilitates a "Pull System," where design is driven by customer demands rather than technical capability (http://abc.truemesh.com/archives/000093.html).

  • Categorization of Test Doubles, distinguishing between mocks, stubs, and so on. Under that categorization, the pattern here describes a "Fake" (http://tap.testautomationpatterns.com:8080/Using%20Test%20Doubles.html).




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net