Assetize

Test Maximo without the shared QA instance

Your Maximo QA instance is the slowest — and most expensive — tool you own.

One shared test box, a booking spreadsheet, and a nightly suite that fails for reasons nobody can reproduce by morning. A red test rarely means your code broke — it means someone reloaded the work-order table mid-run.

The live instance is the slowest test tool you own

A stub is a locally controlled stand-in for a remote system that answers with pre-determined responses — instantly, identically, every time. That modesty is the whole trick.

Against a live Maximo, a test round-trip costs seconds and the answer depends on data state, patch level, current load, and whoever else is testing that morning. Against a stub it costs milliseconds and depends on nothing. A red test means your code changed — not that someone reloaded the work-order table mid-run.

The compounding effect is what convinces teams: suites that ran nightly start running on every save, developers stop serialising on one QA seat, and the failure paths that page you at 2 a.m. become fixtures you serve on demand instead of incidents you wait to observe.

Version awareness — fail closed

Maximo is not one API — it is a family of release lines with genuinely different surfaces. An object structure that gained a field in 9.1 will happily pass tests against a stub built from 9.0 captures while failing in production. An unversioned fixture is a rumour with a JSON extension.

So every fixture carries two things: the release lines it is evidenced for, and where that evidence came from. Requests select a version lens; the stub serves only fixtures tagged for that lens.

And when a test asks for a version the stub has no evidence for, the honest stub refuses — an explicit “no fixture for this version” error rather than a silently reused response from another release line. Fail closed. Say what you don’t know.

The three-layer method

The transport layer speaks Maximo’s wire conventions — OSLC and JSON API paths, auth headers, paging — and is deliberately replaceable: the same fixtures serve through a small Node server, a WireMock mapping set, or a Playwright route interceptor.

The behaviour layer is the fixture store, organised by version lens and functional area, with the negative shapes riding along every happy path: not-found, validation rejection, rate limit, auth failure.

The seam layer is the quiet hero: structure the code under test so its core logic takes plain data in and returns plain results, so most tests need no transport at all. A module that cannot open a connection also cannot accidentally become load on production.

Inside the JVM

Everything above tests Maximo from the outside, at the HTTP boundary. But a lot of Maximo work lives inside the JVM: Java customisations, MBO extensions, automation-script logic that manipulates MboSet and Mbo directly.

A mocked MboSet lets you unit-test a field validation, a save hook, or a cron task’s logic in milliseconds, with no running server and no test database — backed by a real value store and a fail-closed attribute dictionary that throws for attributes a given release line does not have.

Build it & run it live

The theory is only convincing when you can run it. The build page ships a live in-browser terminal — fire reads, writes, an illegal status change, a duplicate-key error, or an unknown attribute, and watch it fail closed.

Underneath sit the real test execution summary, the downloadable stub kit, and ready-to-open starter projects for VS Code, IntelliJ and Eclipse — so the pattern lands in your own editor, not just on the page.

Sources

  • IBM documentation
  • IBM support / lifecycle information
  • Practitioner interpretation

More field guides