Method anySatisfy from assertJ swallows actual failure message - assertj

I use assertJ in my project for nice formulation of test assertions.
I call anySatisfy on a collection where I pass assertions in a lambda that must be met for at least one of the collection elements.
assertThat(myCollection).anySatisfy(myCollectionElement-> {
assertThat(myCollectionElement).callAnyAssertionMethod();
assertThat(myCollectionElement).anotherAssertionMethod();
}
Once no element satisfies the required assertions, anySatisfy fails as expected.
The problem is that the console output then as follows
java.lang.AssertionError:
Expecting any element of:
<allCollectionElementsArSerializedHere>
to satisfy the given assertions requirements but none did.
at myPackage.myTestClass.myTestMethod(MyTestClass.java:xyz)
Concluding I do know that anySatisfy being called in line xyz failed, but I do not get to know which particular assertions inside the lambda are not met. I only can see that in the debugger.
How can I achieve to get the expected log output?

You can't but we have improved allSatisfy to report the unsatisfied requirements.
We will do the same for anySatisfy for the next release, I have created https://github.com/joel-costigliola/assertj-core/issues/1400 to track this.

Related

Is there a simple way to filter & narrow collections on instance type in assertj?

Can this be written as a single line?
assertThat(actualDeltas)
.filteredOn(delta -> delta instanceof Replacement)
.asInstanceOf(InstanceOfAssertFactories.list(Replacement.class))
I expected asInstanceOf to do the filtering. Alternatively, I searched for extractors or other concepts, but couldn't find any simple solution.
Is that possible with assertj?
By design, the purpose of asInstanceOf is only to provide type-narrowed assertions for cases where the type of the object under assertion is not visible at compile time.
When you provide InstanceOfAssertFactories.list(Replacement.class) as a parameter for asInstanceOf, you are telling AssertJ that you expect the object under assertion to be a List with elements of type Replacement.
While asInstanceOf will make sure that the object under test is a List, it will neither filter nor enforce that all the list elements are of type Replacement. The Replacement will ensure type-safety with subsequent methods that can be chained, for example with extracting(Function).
Currently, filteredOn(Predicate) or any other filteredOn variant is the right way to take out elements that should not be part of the assertion. If the filtering would happen outside (e.g., via Stream API), no asInstanceOf call would be needed as assertThat() could detect the proper element type based on the input declaration.

FluentAssertions fails when comparing exception messages

I just updated my old project to use version 4.13.0 and there was a lot of exception validation with ComparisonMode.Substring, but ComparisonMode.Substring does not exist in the newest version. I found this that explains that:
As a result of this, I decided that as of version 2.1, the ComparisonMode is obsolete and any assertions against the exception message is treated as a case-insensitive wildcard match.
But now I get loads of failed tests with:
Expected exception message to match the equivalent of "Value of
argument 'PeriodEnd' must be greater than '01.01.0001'", but "Value
of argument 'PeriodEnd' must be greater than '01.01.0001'. Value is
'01.01.0001'.
Parameter name: PeriodEnd" does not.
string I assert with
Value of argument 'PeriodEnd' must be greater than '01.01.0001'
The one it expects
Value of argument 'PeriodEnd' must be greater than '01.01.0001'. Value is '01.01.0001'.
Parameter name: PeriodEnd
But from the "patch notes" from before it seems that it should be a wildcard, and the string I assert from is a substring of the one it really is, so why does it fail?
You still need to add the wildcard characters to the call to WithMessage, just like you did when ComparisonMode.Wildcard still existed. The rationale is explained in this post:
If you need to verify that a certain string value or exception message matches the expectation, never verify the exact message. Use wildcards to verify the specific parts that are relevant to verify that the behavior meets the expectation. It will save from unexpectingly failing tests if you decide to refine the text involved.

Meaning of 'Ignore potential matches'

Under Window > Preferences > General > Search, there is the option Ignore potential matches
What does it do? Whether I activate it or not, I never see a difference.
Is it an option that only makes sense for Java development (which I never do, but I do develop in C, Python and PHP using Eclipse)?
See bug 127442 for examples: depending on what you are searching (a class, a method, ...), the Search engine can find instances which could match (but it cannot say for certain).
Those instances are marked "POTENTIAL_MATCH":
A method with different number of parameters is not a potential match.
(see bug 97322 )
A potential match is a match where the resolution failed (e.g. the method binding is null).
If the user searches for "foo(String)" (without qualifying String), then "foo(java.lang.String)" and "foo(p.String)" are both exact matches.
For the .class file case, I think we can only have potential matches in the case of the missing type case (see bug 196200), i.e if the .class file was compiled and some types it references were missing.
A current example of potential match misbehavior is found in bug 382778:
I have a public static void method printIt(String name).
When I open its call hierarchy, some callers are missing.
I am guessing the callers are missing because java search marks them as potential instead of exact matches for the printIt(String) reference.
The following code is sometimes marked as potential, and sometimes exact:
// Listing 1
PublicInterface2 impl2 = new Impl2("Name Broken");
Static.printIt(impl2.getName());
When the search result is marked potential, the caller is missing from the printIt() call hierarchy.
PublicInterface2 is an empty public interface which extends PackageInterface2Getters.
PackageInterface2Getters is an empty default-scoped interface which extends PackageInterface1Getters.
PackageInterface1Getters is a default-scoped interface which declares String getName().
So impl2.getName() above returns a String.
There are some problems reported which I guess make the matches be marked as potential:
...
Filename : \D:\workspace\eclipse\_runtimes\jdt\call-hierarchy-bug\src\main\PublicInterface2.java
COMPILED type(s)
2 PROBLEM(s) detected
- Pb(2) PackageInterface1Getters cannot be resolved to a type
- Pb(327) The hierarchy of the type PublicInterface2 is inconsistent
Turns out that:
The compiler asks the "NameEnvironment" to get the type information of any dependent type.
Search has it's own NameEnvironment implementation in JavaSearchNameEnvironment and it is not looking for secondary types.
This is bad and it is surprising that we haven't run into this problem until now.
In Eclipse Luna (Service Release 1 (4.4.1)) I searched just for references to this Java method:
merge(DashboardConfigurationModel template, DashboardModel custom)
It returns two references. One of these calls to the merge() method passes in a DashboardConfigurationModel and a DashboardModel, as befits the method signature. This is a match all right!
The other reference to a merge() method passes in a String and a Map. It is marked in Eclipse as a "potential match" but in my mind, since the argument types don't match, this has zero potential to be a match.
I then checked Ignore potential matches, did the search again, and this noise went away.

Fragment Evaluation Error

Can someone tell me what "Fragment evaluation error" means, or where I might look for solutions? I sometimes (but not always) get lots of these errors (without changing my code):
[error] ! Fragment evaluation error
[error] ThrowableException: Could not initialize class code.model.Post$ (FutureTask.java:138)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply$mcZ$sp(PostSpec.scala:68)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply(PostSpec.scala:51)
[error] code.model.PostSpec$$anonfun$1$$anonfun$apply$1.apply(PostSpec.scala:51)
Line 68 of PostSpec is the first line in the (specs2) test that references the Post model companion object:
val test4 = Post.fixJValue(toextract4).extract[Selection]
I'm using Scala 2.9.0-1.
Also: I have no idea whether it matters, but Post is a net.liftweb.mongodb.record.MongoRecord class companion object:
object Post extends Post with MongoMetaRecord[Post] { ... }
In a specs2 specification, Fragments are pieces of the specification. A Fragment can be a Text, an Example, a Step.
Some fragments, like Example and Step are meant to be executed and are supposed to catch Exceptions so that they can be marked as failures. But they won't catch Errors (except AssertionErrors). So if an Example throws an OutOfMemoryError, this will be reported as a Fragment evaluation error.
Other fragments, like Text fragments are not supposed to throw exceptions when being evaluated. If they do, you will get the same Fragment evaluation error message.
Without seeing the full specification it's hard for me to say what's happening there but I suspect that you had a non-Exception type thrown in the body of an Example. But I have more questions than answers for now:
where is test4 declared? Inside the specification body? Inside a Context case class?
since errors happen intermittently, are you sure you always have a proper mongodb context? Maybe your specification examples are being executed concurrently on the same mongo db instance?

ILGenerator, make decision on return value of null

il.Emit(OpCodes.Callvirt, _compactBinaryReader_ReadObject);
this function is called and at a special condition a return value of 'null' is provided.
if that value is null i have to take a decision whether to jump on to a label or not
using after the method call
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Brfalse_S, DECISION);
gives me an exception "JIT Compiler encountered an internal limitation." when i call that function, the code builds correctly though.
tried OpCodes.Brfalse too.
what am i doing wrong ?
Found reasonS to the above problem,
one thing which should be understood that when an exception of
'CLR: Verification for Runtime Code Generation'
is thrown it means the code written is not in the correct format and when it is evaluated by the assembler it does not accept the written code, problem is usually because of stacks having extra values or less.
"JIT Compiler encountered an internal limitation." is thrown when at runtime it was expecting something else we provide something else in value or when stack has something else when something else was required.
In short, the later exception is thrown at runtime and the other is thrown when pre Run conditions are not met.
anyways i found the reason, i had some values still present on stack that i did not pop if Condition was met, so the POP OpCode did the trick, and by the way for me the Dup OpCode never worked out, it always pushes a null value on stack rather than duplicating the top most value.