It can be done.
Unless it can’t.
There are two key use cases, and they’re quite different.
There is an alternative use case which I think is a very different animal.
- We use a framework like Angular, React or Vue to build an SPA to sit on top of a Java set of APIs
In the other cases, it’s a deeply grey area.
How Do I Know?
The point is. I’ve learned some of this stuff from bitter experience.
It’s kind of not meant to be, yet it still happens.
Before we had a cleaner separation of front end into SPAs, we might use a Java server to render the HTML of the page on each request to the server. We still can. I did a project this way last year.
The request comes to the Java server and the server then executes a template to render the right HTML, including some
There are a couple of challenges:
- Keywords and constructs – e.g.
- Functions – i.e. some library functions aren’t available on all browsers/runtimes, requiring us to add
polyfillsto replace them
While the latest
node runtime, which we might use for unit testing will have EVERYTHING, the target browser might not. So we somehow need to test in the lowest-common denominator runtime.
Even the title makes this seem like a bad idea. However, it’s not entirely a bad thing. In general we do it so that:
- We get the ability to deploy dynamic scripts
- We can mix Java objects and functionality from the server’s context with our scripts
- Create all the Java context that the script consumes
- Ensure all libraries that the script imports are on the classpath
- Execute the script from a unit test
- Assert the output of the script in Java at the end of the execution
This presumes that all of the above is possible. It’s generally possible, with software we wrote. I’ve done it.
One assumption might be that the script returns an assertable value. Maybe it does. Often they don’t just do that. Some scripts also act on the context, and we need to assert what happened to the outside world. In those cases, we have to spy or mock that outside world before running the script. Easier with our own code, harder with someone else’s.
In other words, it’s somewhere from moderately to very not possible.
The simple answer is sure we can. But. This assumes that it’s possible and desirable for such a library to be imported into the target run time.
- For a dynamic script to run in a JVM process, it presumes you can have additional library files, rather than a monolithic dynamic script (spoilers, it’s usually only the latter)
In those instances, the only problem left to solve is the language level project. Let’s be clear, though. When I’ve used
jquery in a web page that’s rendered from Java, I’ve depended on their own unit testing and transpilation.
However, when I’m trying to test in-page control bindings, or when I’m trying to test a scriptlet that runs within a Java low-code process, I don’t necessarily have the ability to “just import a well tested library”.
Oh… and then there was that time that I could use a well tested library, and there was another problem…
It’s a Trap?
This whole subject is easy in theory, and tricky in practice.
It’s not a trap.
It’s just really really nuanced.
The best unit tests are precise, fast-running, and relevant. This means they need to run in the same way (or as near as damn-it) to real runtime, while still allowing us to slice away external dependencies.
In many cases, testing Java server-side-rendered pages is a case of tolerating the long delays caused by waiting for the DOM in HtmlUnit, or even a real browser, to actually render the page and then probing it.
There are occasional easy wins within this subject, but they cannot often be 100% trusted.