Assertion of Particular Exception which contains a field - java

Currently I have a test which tries to check a particular exception which looks like this:
assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
() -> xrepo.save(abc))
.withCauseExactlyInstanceOf(ConstraintViolationException.class);
The exception ConstraintViolationException has a field constraintName available via getter getConstraintName() but I haven't found a way to check that via assertj.
I could imagine something like the following:
assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
() -> xrepo.save(abc))
.withCauseExactlyInstanceOf(ConstraintViolationException.class)
.with("getConstraintName").isEqualTo("XXXX");
or is there a different way to accomplish this?

withCauseExactlyInstanceOf does not change the object under test, but with havingCause() further assertions can be performed on the cause.
Combined with asInstanceOf() and returns(), a type-safe check would be:
assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
() -> xrepo.save(abc))
.havingCause()
.asInstanceOf(type(ConstraintViolationException.class))
.returns("XXXX", from(ConstraintViolationException::getConstraintName));
Or without type safety, using isInstanceOf and hasFieldOrPropertyWithValue:
assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
() -> xrepo.save(abc))
.havingCause()
.isInstanceOf(ConstraintViolationException.class)
.hasFieldOrPropertyWithValue("getConstraintName", "XXX")

May be:
.extracting(x -> ((ConstraintViolationException)x).getConstraintName())
.isEqualTo("XXXX");

The solution of #Eugene brought me to the direction:
assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
() -> xyrepository.save(xxx))
.withCauseExactlyInstanceOf(ConstraintViolationException.class)
.extracting(s -> ((ConstraintViolationException) (s.getCause())).getConstraintName())
.isEqualTo("XXXX");
The solution of #StefanoCordio looks also fine...

Related

Java streams peek() equivalent in Mutiny Quarkus

Sometimes I want to peek what's the value that is flowing through the steam.
I cannot attach a debugger from my IDE. Because I will see unresolved objects instead of values. If I try to .await().indefinetely() it will raise an exception.
So I'm looking for something like in java streams I can simply use peek(e -> System.out.println(e)) which will simply print the value.
I have something like below
public Uni<TenantDraft> getTenantById(#PathParam("tenantKey") String tenantKey) {
return tenantService.findByTenantKey(tenantKey)
.onItem().ifNotNull().transform(TenantMapper.INSTANCE::tenantToTenantDraft)
.onItem().ifNull().failWith(ForbiddenException::new);
}
You can either use:
.log() which will log all the event
.invoke(item -> System.out.println(item))

Using Optional's ifPresentOrElse method but return promise instead of void

I'm trying to get my around a current issue I'm facing.
I have a function that returns an Optional type (an object with a few properties)
One of the properties is an url that might be present or not. I extract that url in order to make an HTTP request
injectedClass.method(tenant.clientKey()).flatMap(optionalProperty ->
optionalProperty.ifPresentOrElse(fi -> {
Blocking.get(() -> httpClientProvider.withHttpClient((HttpClient httpClient) ->
httpClient.request(URI.create(optionalProperty.webTriggerUrl()), (RequestSpec spec) -> {
LogstashMarker markers = append("webTriggerUrl", fi.webTriggerUrl()).and(append("method", "Post").and(append("behaviour", objectMapper.writeValueAsString(baseDTO))));
logger.debug(markers, "Executed a Post request to something webTriggerUrl");
spec.method(HttpMethod.POST);
spec.getBody().type(HttpHeaderValues.APPLICATION_JSON).text(objectMapper.writeValueAsString(baseDTO), CharsetUtil.UTF_8);
final MutableHeaders headers = spec.getHeaders();
headers
.set(HttpHeaderNames.USER_AGENT, userAgent);
headers.set(CorrelationId.HEADER_NAME, correlationId.id());
})
)).then(resp -> logger.info("ok"));
}, () -> logger.error("something"))
Blocking.get brings back a Promise and I get an error in my code basically saying that the expected return type of ifPresentOrElse should be void and not Promise
Is there a functional and better way to achieve this?
Yes there are ways, but you also have to decide what to do if the Optional is empty. Currently you want to return a Promise if the optional is present, and return nothing ("void") if it is empty. This doesn't work, the types for both branches need to be the same.
You can just use optionalProperty.map() to map your original Optional to a Optional<Promise>, and then use ifPresentOrElse, to do something with either the Promise or with the empty Optional, e.g. logging as you seem to be doing in your case.
But you also have a higher-level flatMap which I'm unclear from which type it is. Does this flatmap a Promise? Then you must return a Promise also from the other branch of the optional, and you could use optionalProperty.map(...).orElse( <create empty Promise here> ).
Also check out orElseGet() instead of orElse(), if you want to create the empty branch lazily (via Supplier).
ifPresentOrElse returns void. What you probably want is a combination of map and orElseGet:
optionalProperty.map(/* code to return a Promise */)
.orElseGet(() -> /* code to return a Promise that is immediately resolved */);
Inside the supplier to orElseGet() you can put your logger.error statement.

How to use Optional's map and orElseGet methods when calling a void method based on the optional value

I have a Java Optional variable that I'm using as below.
Optional<Forms> formsOptional = input.data().get().forms();
if(formsOptional.isPresent()) {
this.doSomething(myValue, forms.get());
} else {
this.doSomething(myValue, Forms.builder().names(myList).build());
}
In this case, doSomething method is a void method that does something. As this is a void method, I'm confused about how I can use the map().orElseGet(), as I don't have anything to transform as well. Any suggestions to optimize this piece of code using any Java8 Optional techniques would be much appreciated.
Use orElseGet(other), so the builder expression doesn't get executed if the value is present.
Optional<Forms> formsOptional = input.data().get().forms();
Forms forms = formsOptional.orElseGet(() -> Forms.builder().names(myList).build());
this.doSomething(myValue, forms);
You would normally do that as part of the previous method chain, which you might split on multiple lines, for clarify, if needed:
Forms forms = input.data()
.get()
.forms()
.orElseGet(() -> Forms.builder().names(myList).build());
this.doSomething(myValue, forms);
You already have the best with java-8 version, but if you are using java-9 or higher you can use ifPresentOrElse
formsOptional.ifPresentOrElse(val -> doSomething(myValue, val),
() -> doSomething(myValue, Forms.builder().names(myList).build()));

What is the top first use case you think of, when you see the 'flatMap' method in someone else's code?

Sorry for some kind of theoretical question, but I'd like to find a way of quick reading someone else's functional code, building chain of methods use templates.
For example:
Case 1.
When I see use of .peek method or .wireTap from Spring Integration, I primarily expect logging, triggering monitoring or just transitional running external action, for instance:
.peek(params ->
log.info("creating cache configuration {} for key class \"{}\" and value class \"{}\"",
params.getName(), params.getKeyClass(), params.getValueClass()))
or
.peek(p ->
Try.run(() -> cacheService.cacheProfile(p))
.onFailure(ex ->
log.warn("Unable to cache profile: {}", ex.toString())))
or
.wireTap(sf -> sf.handle(msg -> {
monitoring.profileRequestsReceived();
log.trace("Client info request(s) received: {}", msg);
Case 2.
When I see use of .map method or .transform from Spring Integration, I understand that I'm up to get result of someFunction(input), for instance:
.map(e -> GenerateTokenRs.builder().token(e.getKey()).phoneNum(e.getValue()).build())
or
.transform(Message.class, msg -> {
ErrorResponse response = (ErrorResponse) msg.getPayload();
MessageBuilder builder = some tranforming;
return builder.build();
})
Current case.
But I don't have such a common view to .flatMap method.
Would you give me your opinion about this, please?
Add 1:
To Turamarth: I know the difference between .map and .flatMap methods. I actively use both .map, and .flatMap in my code.
But I ask community for theirs experience and coding templates.
It always helps to study the signature/javadoc of the streamish methods to understand them:
The flatMap() operation has the effect of applying a one-to-many transformation to the elements of the stream, and then flattening the resulting elements into a new stream.
So, typical code I expect, or wrote myself:
return someMap.values().stream().flatMap(Collection::stream)
The values of that map are sets, and I want to pull the entries of all these sets into a single stream for further processing here.
In other words: it is about "pulling out things", and getting them into a stream/collection for further processing.
I've found one more use template for .flatMap.
Let's have a look at the following code:
String s = valuesFromDb
.map(v -> v.get(k))
.getOrElse("0");
where Option<Map<String, String>> valuesFromDb = Option.of(.....).
If there's an entry k=null in the map, then we'll get null as a result of code above.
But we'd like to have "0" in this case as well.
So let's add .flatMap:
String s = valuesFromDb
.map(v -> v.get(k))
.flatMap(Option::of)
.getOrElse("0");
Regardless of having null as map's value we will get "0".

Configure mockito to print actual argument values in verification error messages

When describing failed verification, by default Mockito prints only call sites where interactions happened. Like this:
Wanted but not invoked:
proxyListener.foundTemplateParam(
"fooBar2",
isNull(),
isNull()
);
-> at foo.ProxyHandlerTest.testThatImplicitParamsScannedCorrectly(ProxyHandlerTest.java:136)
However, there were other interactions with this mock:
-> at foo.ProxyHandler.<init>(ProxyHandler.java:99)
-> at foo.ProxyHandler.<init> (ProxyHandler.java:100)
-> at foo.ProxyHandler.scanForParamSetters(ProxyHandler.java:222)
-> at foo.ProxyHandler.<init>(ProxyHandler.java:102)
-> at foo.ProxyHandler.<init>(ProxyHandler.java:104)
That's useful information but I would also like to see what arguments where passed during those interactions. Is there a way to achieve this?
P. S. I know about mocking with withSettings().verboseLogging(). But it's too verbose and is printed to stdout instead of adding this info to assertion error message.
Update:
Mockito 1.9.0 doesn't support customization of exception error messages out of the box (I just checked their sources).
the safest place to do that is an answer that prints arguments and return the given value.
You could then write something like :
given(some.callWith(arg1, arg2)).will(printArgsAndReturn("some value"));
where printArgsAndReturn("some value") actually returns your custom answer.

Categories