Class MockModerationModel
- All Implemented Interfaces:
ModerationModel
ModerationModel for tests: it needs no network, moderates the way the test tells it to, and records the
requests it receives.
Script the answers step by step, one step per request. One call of moderate(...) is one request, also when it
moderates several messages. For example, a model that flags nothing, however often it is called:
MockModerationModel model = MockModerationModel.thatDoesNotFlag().thenRepeats();
Every that... method creates a mock with its first step, and every then... method adds a step. Each
step answers exactly one request. A request after the last step fails with an IllegalStateException that
shows the texts of the request, so a test notices when the code calls the model more often than the script expects,
unless the code under test handles the error itself. So a mock that is called more than once, for example to
moderate every message of a conversation, ends its script with thenRepeats(), which answers every further
request with the last step.
A script can let a request fail and the next one succeed, for example to test what your application does when the
moderation service times out for one message, with LangChain4j's TimeoutException, and then works again:
MockModerationModel model = MockModerationModel.thatFails(new TimeoutException("Read timed out"))
.thenDoesNotFlag()
.thenRepeats();
Or it can flag the first message and accept the next ones:
MockModerationModel.thatFlags("How do I hack ...").thenDoesNotFlag().thenRepeats(). To flag a message by its
content, compute the moderation from the request with thatModerates(Function).
Like on every mock in this package, thatResponds(...) and thenResponds(...) give a step as the whole
response, here a ModerationResponse: the request is answered with exactly that response, including its
metadata.
A mock remembers which steps were taken and which requests it received, so create a new one for each test. A mock
shared between tests, for example as a bean, fails with a clear message as soon as its script runs out, unless the
script ends with thenRepeats(). The steps are taken in the order the requests arrive. A mock keeps every
request it receives, so it is not meant for load tests or other long runs.
-
Method Summary
Modifier and TypeMethodDescriptiondoModerate(ModerationRequest moderationRequest) Performs the actual moderation.The last request received so far.Returns the list of listeners for this moderation model.request()The only request received so far.requests()A copy of the requests received so far, in the order they arrived.static MockModerationModelA model that does not flag the first request.static MockModerationModelthatFails(RuntimeException exception) A model whose first request fails with exactly the given exception.static MockModerationModelA model that flags the first request, reporting the given text as the flagged one.static MockModerationModelthatModerates(Function<ModerationRequest, Moderation> moderation) A model that computes the moderation of the first request from the request.static MockModerationModelthatResponds(ModerationResponse response) A model that answers the first request with exactly the given response, including its metadata, to test code that reads it:Adds a step: the next request is not flagged.thenFails(RuntimeException exception) Adds a step: the next request fails with exactly the given exception.Adds a step: the next request is flagged, with the given text reported as the flagged one.thenModerates(Function<ModerationRequest, Moderation> moderation) Adds a step: the moderation of the next request is computed from the request.Answers every further request with the last step of the script.thenResponds(ModerationResponse response) Adds a step: the next request is answered with exactly the given response, including its metadata, seethatResponds(ModerationResponse).withListeners(ModerationModelListener... listeners) Notifies the given listeners of each call, like a real model does.withListeners(List<ModerationModelListener> listeners) Notifies the given listeners of each call, like a real model does.
-
Method Details
-
thenFlags
Adds a step: the next request is flagged, with the given text reported as the flagged one. The text is not compared with the request, seethatFlags(String).- Throws:
IllegalStateException- if the script already ends withthenRepeats()
-
thenDoesNotFlag
Adds a step: the next request is not flagged.- Throws:
IllegalStateException- if the script already ends withthenRepeats()
-
thenModerates
Adds a step: the moderation of the next request is computed from the request.- Throws:
IllegalStateException- if the script already ends withthenRepeats()
-
thenResponds
Adds a step: the next request is answered with exactly the given response, including its metadata, seethatResponds(ModerationResponse).- Throws:
IllegalStateException- if the script already ends withthenRepeats()
-
thenFails
Adds a step: the next request fails with exactly the given exception.- Throws:
IllegalStateException- if the script already ends withthenRepeats()
-
thenRepeats
Answers every further request with the last step of the script. Only the last step repeats; the script does not start over. A last step that computes its moderation computes it again for each request. Without it, a request after the last step fails. It must be the last call of the script.- Throws:
IllegalStateException- if the script already ends withthenRepeats()
-
withListeners
Notifies the given listeners of each call, like a real model does. -
withListeners
Notifies the given listeners of each call, like a real model does. -
doModerate
Description copied from interface:ModerationModelPerforms the actual moderation. This method should be overridden by implementations.- Specified by:
doModeratein interfaceModerationModel- Parameters:
moderationRequest- the moderation request.- Returns:
- the moderation response.
-
listeners
Description copied from interface:ModerationModelReturns the list of listeners for this moderation model.- Specified by:
listenersin interfaceModerationModel- Returns:
- the list of listeners, or an empty list if none are registered.
-
requests
A copy of the requests received so far, in the order they arrived. -
request
The only request received so far.- Throws:
IllegalStateException- if the mock received no request or several requests
-
lastRequest
The last request received so far.- Throws:
IllegalStateException- if the mock received no request
-
thatFlags
A model that flags the first request, reporting the given text as the flagged one. The text is not compared with the request: this step flags the next request, whatever it contains. A real moderation model reports the first flagged text of the request, so pass one of the texts that the code under test sends. To flag only some texts, compute the moderation from the request:
Add the next steps withMockModerationModel model = MockModerationModel.thatModerates(request -> request.texts().stream() .filter(text -> text.contains("hack")) .findFirst() .map(Moderation::flagged) .orElseGet(Moderation::notFlagged)) .thenRepeats();then...methods, or flag every request:thatFlags("...").thenRepeats(). -
thatDoesNotFlag
A model that does not flag the first request. Add the next steps withthen...methods, or flag nothing:thatDoesNotFlag().thenRepeats(). -
thatModerates
A model that computes the moderation of the first request from the request. Add the next steps withthen...methods, or compute the moderation of every request withthenRepeats(). If the function throws, the request fails with that exception, unchanged. -
thatResponds
A model that answers the first request with exactly the given response, including its metadata, to test code that reads it:
The metadata depends on the provider, and many moderation models report none. Add the next steps withMockModerationModel model = MockModerationModel.thatResponds(ModerationResponse.builder() .moderation(Moderation.flagged("My phone number is 555-0100")) .metadata(Map.of("detection_type", "pii", "score", 0.97)) .build());then...methods, or answer every request with this response:thatResponds(response).thenRepeats(). -
thatFails
A model whose first request fails with exactly the given exception. To let every request fail, addthenRepeats(). To let later requests succeed, for example to test how your application handles a moderation service that is down for a moment, add steps withthen...methods.
-