The short answer to "Is there any standard or accepted way to do something like this?" would be: no.
This is mainly because you don't want your UI to know this kind of information at all. You want your UI to just be your UI. As soon as your UI starts taking some decisions based on whether it's in "test mode" or "production mode", you embark on a slippery slope that will ultimately lead to a nightmare code-base.
This does not mean your problem cannot be solved; just that the solution should be approached in a different way. I'll first explain the general principles without any language specifics, then provide some guidelines for javascript.
General Principles
The only reason for you to be struggling with this is that your UI is too tightly coupled to the API.
The solution happens to be exactly the same as any situation when you wish to use mocks.
- Program to an interface, not an implementation. (Ensure your UI binds only to an abstraction of the API - not the "true/production API".)
- Separate instantiation from interaction. (Don't let your UI create any of its API dependencies, because that binds it to a specific implementation - rather provide interface on the UI for it to be given the specific API instance it should use.)
Program to an interface
First note that the above phrase does not mean your language needs to support an "interface" construct. (It's just an unfortunate choice of name by some language implementors.)
- Define a base class/object which defines each of the methods/messages that your API should support. (However, none of these will actually be implemented on the base class/object.)
- Your UI should have a variable/field/reference to the APIInterface.
- Your UI will call the methods it needs from the API via the interface reference. E.g.
APIRef.DoMethod1(...)
or APIRef->DoMethod1(...)
or [APIRef DoMethod1:...]
etc.
Separate instantiation from interaction
The thing to avoid here is:
CreateUI {
APIRef = CreateAPI;
}
The above binds your UI to a specific implementation, and forces you to include those files/dependencies in your UI code. You would rather have your UI be told which API to use. E.g.
CreateUI(APIInterface APIToUse) { //NB: Notice that the type use to refer
//to the API is the abstract base type
//defined earlier (keeping to the "Program
//to an interface" principle).
APIRef = APIToUse;
}
//or
SetAPI(APIInterface APIToUse) {
APIRef = APIToUse;
}
Now your production application could look something like this:
API = CreateTrueAPI;
UI = CreateUI(API);
Whereas your test application could look something like this:
API = CreateMockAPI;
UI = CreateUI(API);
Notice how with this solution, your UI doesn't have a clue about "test mode" or "production mode". It just uses the API it is given. The only thing that knows about the "test mode" (in a manner of speaking) and the mock API is the test application.
Applying the principles to Javascript
First, let me state for the record: although I am familiar with the language principles of Javascript, I have never done JS development. So there may be some unforeseen complications. However, in the worst case, with a little tweaking and research, I'm sure you'll figure something out.
Javascript supports duck-typing which basically means you can send any message to any object, and at runtime the object will decide if it can actually process the message. You lose out on compile-time checking that you haven't made any typo errors, but as I understand it: you don't really need to define the abstract base interface at all.
So...
- Simply ensure your UI has a reference to an API object.
- Ensure your UI doesn't include any API implementation files (neither the true/production version nor the mock version).
- In your production host create the true API, create the UI and pass the true API to the UI.
- In your test host create the mock API, create the UI and pass the mock API to the UI.