AssertJ is a library providing easy to use rich typed assertions

Overview

AssertJ - Fluent assertions for java

Github CI status Github Cross-Version status Binary Compatibility Maven Central Javadocs Quality Gate Status

AssertJ provides a rich and intuitive set of strongly-typed assertions to use for unit testing (with JUnit, TestNG or any other test framework).

You can ask questions in stackoverflow (assertj tag) and make suggestions by simply creating an issue.

AssertJ's goals

AssertJ's ambition is to provide a rich and intuitive set of strongly-typed assertions for unit testing.

The idea is that disposal assertions should be specific to the type of the objects we are checking when writing unit tests. If you're checking the value of a String, you use String-specific assertions. Checking the value of a Map? Use Map-specific assertions to easily check the contents of the map.

AssertJ's assertions are super easy to use: just type assertThat(underTest). and use code completion to show you all assertions available.

Assertion missing? Please create an issue to discuss it and even better contribute to the project!

AssertJ is composed of several modules:

Want to contribute?

You are encouraged to contribute any missing useful assertions.

Please read the contributing section and raise a PR!

Comments
  • Java module descriptor for `org.assertj.core`

    Java module descriptor for `org.assertj.core`

    Old caption

    [ByteBuddy] NoClassDefFoundError: java.lang.instrument.Instrumentation

    Summary

    Running tests included in JUnit 5's documentation project (backing the User Guide) on the class-path works fine. Converting those tests and demos into a Java module and running it on the module-path fails with several errors. One of the error is related to AssertJ/ByteBuddy.

    Found this issue while working on https://github.com/junit-team/junit5/issues/1877

    /cc @raphw

      JUnit Jupiter:EngineTestKitAllEventsDemo:verifyAllJupiterEvents()
        MethodSource [className = 'example.testkit.EngineTestKitAllEventsDemo', methodName = 'verifyAllJupiterEvents', methodParameterTypes = '']
        => java.lang.IllegalArgumentException: Could not create type
           [email protected]/org.assertj.core.internal.bytebuddy.TypeCache.findOrInsert(TypeCache.java:154)
           [email protected]/org.assertj.core.internal.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:365)
           [email protected]/org.assertj.core.api.SoftProxies.createSoftAssertionProxyClass(SoftProxies.java:118)
           [email protected]/org.assertj.core.api.SoftProxies.createSoftAssertionProxy(SoftProxies.java:104)
           [email protected]/org.assertj.core.api.AbstractSoftAssertions.proxy(AbstractSoftAssertions.java:31)
           [...]
         Caused by: java.lang.NoClassDefFoundError: java/lang/instrument/Instrumentation
           [email protected]/org.assertj.core.internal.bytebuddy.utility.JavaModule$Dispatcher$CreationAction.run(JavaModule.java:270)
           [email protected]/org.assertj.core.internal.bytebuddy.utility.JavaModule$Dispatcher$CreationAction.run(JavaModule.java:251)
           java.base/java.security.AccessController.doPrivileged(Native Method)
           [email protected]/org.assertj.core.internal.bytebuddy.utility.JavaModule.<clinit>(JavaModule.java:45)
           [email protected]/org.assertj.core.internal.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$CreationAction.run(ClassInjector.java:454)
           [...]
         Caused by: java.lang.ClassNotFoundException: java.lang.instrument.Instrumentation
           java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
           java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
           java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
           [...]
    

    Side note: Nice to see the AssertJ's version 3.12.2 compiled into its module! :+1:

    opened by sormuras 68
  • 3.9.1 has bad performance regression

    3.9.1 has bad performance regression

    Summary

    After upgrading to 3.9.1, I notice a regression in term of performance. By digging down, I notice that it spends a lot of time in the following code

      public static TypeComparators defaultTypeComparators() {
        TypeComparators comparatorByType = new TypeComparators();
        comparatorByType.put(Double.class, new DoubleComparator(DOUBLE_COMPARATOR_PRECISION));
        comparatorByType.put(Float.class, new FloatComparator(FLOAT_COMPARATOR_PRECISION));
        return comparatorByType;
      }
    

    It sounds like it performs too much memory allocation and reflection cost on the following stack trace.

    java.lang.Class.getEnclosingMethod0() Class.java (native)
    java.lang.Class.getEnclosingMethodInfo() Class.java:1072
    java.lang.Class.getEnclosingClass() Class.java:1272
    java.lang.Class.getSimpleBinaryName() Class.java:1443
    java.lang.Class.getSimpleName() Class.java:1309
    org.assertj.core.internal.TypeComparators$$Lambda$77.apply(Object)
    java.util.Comparator.lambda$comparing$77a9974f$1(Function, Object, Object) Comparator.java:469
    java.util.Comparator$$Lambda$78.compare(Object, Object)
    java.util.TreeMap.compare(Object, Object) TreeMap.java:1295
    java.util.TreeMap.put(Object, Object) TreeMap.java:538
    org.assertj.core.internal.TypeComparators.put(Class, Comparator) TypeComparators.java:99
    org.assertj.core.internal.TypeComparators.defaultTypeComparators() TypeComparators.java:48
    org.assertj.core.api.AbstractIterableAssert.<init>(Iterable, Class) AbstractIterableAssert.java:112
    org.assertj.core.api.FactoryBasedNavigableIterableAssert.<init>(Iterable, Class, AssertFactory) FactoryBasedNavigableIterableAssert.java:32
    org.assertj.core.api.IterableAssert.<init>(Iterable) IterableAssert.java:49
    org.assertj.core.api.Assertions.assertThat(Iterable) Assertions.java:2586
    

    This additional overhead is caused by the change from HashMap to TreeMap and the use of Comparator.comparing(Class::getSimpleName)

    assertj 3.8.0 does not have this problem.

    opened by testn 63
  • Skeleton PathAssert, plus tests -- NOT FOR INCLUSION. Yet.

    Skeleton PathAssert, plus tests -- NOT FOR INCLUSION. Yet.

    Skeleton based on existing code. I modeled it on FileAssert. In fact I saw nothing related to anything java.nio.file in the code, so I created it from scratch...

    Preview only. I know the coding style does not fit; knowing that I use IDEA, do you happen to have a style file available?

    Also, about error messages: there seem to be a lot of factories; FileAssert seems to basically use one per message! Is that on purpose? Can I create a single factory for Path-specific operations (including exists, non exists and absolute)?

    Please comment! I'll add more test when the base is good enough for you.

    opened by fge 47
  • SoftAssertions for JUnit Jupiter should reset tracked exceptions between tests

    SoftAssertions for JUnit Jupiter should reset tracked exceptions between tests

    Overview

    The following code looks up tracked exceptions in an instance field.

    https://github.com/joel-costigliola/assertj-core/blob/9692f7dc339765e9d7ef2725c89b3241c613268f/src/main/java/org/assertj/core/api/JUnitJupiterSoftAssertions.java#L45

    The problem with doing that is that the tracked exceptions do not get reset between test method invocations if the test class is configured with @TestInstance(PER_CLASS) lifecycle semantics, since the test instance is cached along with the instance of JUnitJupiterSoftAssertions stored in an instance field.

    I became aware of this due to the following comment in JUnit's issue tracker: https://github.com/junit-team/junit5/issues/1500#issuecomment-459720295

    Affected Extensions

    • JUnitJupiterSoftAssertions
    • JUnitJupiterBDDSoftAssertions
    • any other extensions implemented in a similar manner

    Proposals

    Modify JUnitJupiterSoftAssertions so that it implements JUnit Jupiter's BeforeEachCallback extension API and clears the collected errors in SoftProxies before each test method.

    Another option would be to store the collected errors in Jupiter's ExtensionContext.Store for the currently executing scope.

    Relate Issues

    • #1229
    opened by sbrannen 44
  • Recursive comparison api improvements

    Recursive comparison api improvements

    Recursive comparison api

    Here's an example to give users an idea of what it looks like:

    assertThat(person).usingRecursiveComparison()
                      .ignoringNullFields()
                      .ignoringFields("name", "age")                                                 
                      .forcingRecursiveComparisonFor(Child.class, Sister.class)
                      .isEqualTo(expectedPerson);
    

    This will be in Beta as it might change according to people's feedback.

    Requirements

    Recursive comparison Fluent API configuration

    Implements an easy to use/discover API as in:

    assertThat(person).usingRecursiveComparison()
                      .ignoringNullFields()
                      .ignoringFields("name", "age")                                                 
                      .isEqualTo(expectedPerson);
    
    • [x] expose ignoring actual null fields
    • [x] expose ignoring fields
    • [x] expose ignoring overridden equals
    • [x] expose setting a comparison strategy per fields/types
    • [x] expose enabling strict type checking
    • [x] documentation

    Ignoring fields in comparison

    Users can specify the comparison to ignore all null fields in the object under test.

    Users can specify to ignore specific fields in the object under test:

    • giving their full path, ex: person.sister.name
    • by regex, ex: .*name means name, person.name and person.sister.name are ignored.

    Note if you ignore specific field, all sub fields are ignored too, for example if person is ignored then person.name, person.address, person.address.number are ignored too.

    Nice to have: report all the fields ignored in the comparison

    status

    • [x] ignore all null fields
    • [x] ignore fields specified with a full path
    • [ ] fail if an ignored fields specified with a full path does not match any field
    • [x] ignore fields specified with a regex
    • [x] report the fields configured to be ignored in the comparison
    • [ ] report all the fields actually ignored in the comparison (to show which fields the regex matched)
    • [ ] documentation

    Allow to use overridden equals method or not

    By default the recursive comparison will use equals if it had been overridden but users should be able to specify to ignore overridden equals methods and compare objects field by field.

    This can be done:

    • for all types matching given regexes
    • a specific given list of types with forcingRecursiveComparisonFor(Child.class, Sister.class)
    • a specific given list of fields with forcingRecursiveComparisonForFields("child", "sister") Nice to have

    Example:

    assertThat(person).usingRecursiveComparison()
                      .forcingRecursiveComparisonFor(Child.class, Sister.class)
                      .forcingRecursiveComparisonForFields("name", "city")
                      .isEqualTo(expectedPerson);
    

    status

    • [x] disable use of overridden equals method for types matching given regexes
    • [x] disable use of overridden equals method for given types
    • [x] disable use of overridden equals method for given fields
    • [x] disable use of overridden equals method for all fields
    • [x] documentation

    Specify a comparison strategy per type or fields

    Users should be able to specify a comparator for a given type or fields:

    • usingComparatorForType(String.class, caseInsensitiveComparator) for all types
    • usingComparatorForFields(caseInsensitiveComparator, "name", "city") a specific given list of fields (vararg)

    To keep the API simple once a comparator for a given type is registered it should be used at any level, collection element or collection element field.

    Field comparators take precedence over type ones as they are more fine grained.

    Once a comparator is registered for a type or a field, it replaces the recursive comparison when these types/fields are being compared.

    status

    • [x] enable a comparison strategy per type
    • [x] enable a comparison strategy per fields
    • [x] documentation

    Strict/lenient type checking

    This will specify if two instances with the same fields but from different classes are considered equals, it allows for example to compare a Person with a PersonDto. If the check is strict the expected object class must be compatible (i.e. extends) actuals, so if Employee inherits Person one can compare a person with an employee (but not an employee with a person. The check is performed on the root objects and their fields.

    By default the check is lenient but it can be made strict to fail the comparison.

    status

    • [x] enable strict type checking
    • [ ] lenient type checking should allow comparing collections of different type (ex TreeSet vs HashSet).
    • [ ] documentation

    Handle cycles

    The recursive comparison should handle cycles, for example when a -> b -> c -> a.

    status

    • [ ] more tests with cycles
    • [ ] documentation

    Map support

    Maps entries should be considered as fields. See if it is possible and relevant to report all compared maps internal differences (size, missing elements, elements differences, order when order is consistent ...) instead just reporting that the maps differ.

    status

    On hold at the moment as it is not crystal what can be achieved reasonably.

    • [ ] map support
    • [ ] documentation

    Iterable/array support

    At the moment assertThat(Iterable/array) does not expose usingRecursiveComparison() which makes it cumbersome to test them field/field.

    The comparison by default fails if we compare an ordered collection to an unordered one but this should be configurable

    Nice to have: ignores order in comparison (by default elements are compared in order for ordered collection). Nice to have: allow to compare ordered collections with unordered one. (this should be disabled by default) Nice to have: allow to compare array with ordered collections like list. (this should be disabled by default)

    Example:

    assertThat(fellowshipOfTheRing).usingRecursiveComparison()
                                   .contains(frodo, sam, merry, pippin, gandalf, 
                                             legolas, boromir, aragorn, gimli);
    

    status

    • [ ] provide elements recursive comparison out of the box for iterable assertions
    • [x] ignores order in comparison (by default elements are compared in order for ordered collection).
    • [x] allow to compare ordered collections with unordered one. (this should be disabled by default)
    • [ ] allow to compare array with ordered collections like list. (this should be disabled by default)
    • [ ] documentation

    Error reporting

    A failure must report the recursive comparison specification:

    • comparators used per type
    • comparators used per fields
    • ignored fields
    • when overridden equals are used and not used

    The failure should show the number of differences and describe them all.

    A difference describes fields by their full path from the root object, the actual value, the expected one and the comparison used if the user specified one. Values are represented with AssertJ standard representation or the one set by the user.

    Actual and expected values type should be displayed when strict type checking is enable.

    The differences reported must be ordered by path alphabetically.

    Difference report example:

    person.sister.name differs: 
    - actual value  : "Sansa"
    - expected value: "Arya"
    - comparison was performed with caseInsensitiveComparator 
    

    The path to field must support maps and adress https://github.com/joel-costigliola/assertj-core/issues/1303.

    status

    • [x] basic error reporting
    • [x] error reporting : show comparators used
    • [ ] error reporting : list ignored fields
    • [x] error reporting : show that actual's null field were ignored in the comparison
    • [ ] error reporting : show which overridden equals were used
    • [ ] error reporting : the path to field must support maps
    • [ ] error reporting : report the index of the indexes of ordered collection field element, ex: friends[1].number
    • [x] error reporting : the differences reported must be ordered by path alphabetically

    Globally configuring the recursive comparison behavior

    To avoid repeating the same recursive configuration before each assertion, AssertJ should provide:

    • a global way to configure the default recursive comparison behavior
    • a way capture easily on the recursive comparison configuration in order to reuse it

    Changing the default recursive comparison behavior before all tests

    AssertJ will extend the mechanism used to configure Representation.

    Capture the recursive comparison setting to reuse it

    If users don't want to change the default behavior globally but on a smaller scope, it will possible to capture a recursive comparison specification and reuse it.

    Example:

    // default behavior
    RecursiveComparisonSpecification recursiveComparisonSpecification =  new RecursiveComparisonSpecification();
    recursiveComparisonSpecification.ignoreNullFields();
    recursiveComparisonSpecification.forceRecursiveComparisonFor(Child.class, Sister.class);
    
    assertThat(person).usingRecursiveComparison(recursiveComparisonSpecification)
                      .isEqualTo(expectedPerson);
    
    assertThat(person2).usingRecursiveComparison(recursiveComparisonSpecification)
                       .isEqualTo(expectedPerson2);
    

    The example above is equivalent to this where we have to repeat call to ignoringNullFields and forcingRecursiveComparisonFor for each assertions:

    assertThat(person).usingRecursiveComparison()
                      .ignoringNullFields()
                      .forcingRecursiveComparisonFor(Child.class, Sister.class)
                      .isEqualTo(expectedPerson);
    
    assertThat(person2).usingRecursiveComparison(recursiveComparisonSpecification)
                       .ignoringNullFields()
                       .forcingRecursiveComparisonFor(Child.class, Sister.class)
                       .isEqualTo(expectedPerson2);
    

    status

    • [ ] provide a way to globally configure the recursive comparison behavior

    Tests checklist

    The recursive comparison specification must be transferred after calling methods that change the object under test: extracting, asString ...

    status

    • [ ] test recursive comparison is propagated

    Initial issue description

    The current way comparing objects recursively is starting to pollute the api, the methods introduced for the recursive comparison don't apply for the other assertion cluttering the assertj api, ex usingComparatorForType.

    I would like to introduce a separate API to use recursive comparison allowing to fine tune the comparison behavior.

    API rough draft (please criticize it !)

    import static RecursiveComparisonSpecification;
    
    // ignoringNullFields() comes from RecursiveComparisonSpecification
    assertThat(person).usingRecursiveComparison(ignoringNullFields()
                                               .ignoringFields("name", "age")                                                 
                                               .forcingRecursiveComparisonFor(Child.class, Sister.class))
                      .isEqualTo(expectedPersont)
    
    theme: recursive comparison 
    opened by joel-costigliola 35
  • Use byte buddy instead of cglib

    Use byte buddy instead of cglib

    Check List:

    • Related to: #928
    • Unit tests : NA
    • Javadoc with a code example (API only) : NA

    With this PR I am dropping cglib and adding bytebuddy as a dependency. I still have not removed the shading. One test is failing due to ClassCastException, and I am not entirely sure how I can resolve it. Maybe @raphw can help out a bit 😄. The issue is in the ErrorCollector#intercept method.

    I think that we should not be shading bytebuddy. Their recommendation is that you should shade if you use the exposed ASM, which I am not. Also the other major players such as Mockito are pulling it as a dependency (we could do it as an optional one or provide 2 modules, one with normal assertions and another with soft).

    Something that I noticed with bytebuddy is that you can theoretically generate the bytecode and ship that as part of the AssertJ release (that way you have no dependency on anything during runtime)

    opened by filiphr 34
  • Fix the bugs of float/double precision error in the assertions

    Fix the bugs of float/double precision error in the assertions

    Check List:

    • Fixes #2537
    • Unit tests : YES
    • Javadoc with a code example (on API only) : YES
    • PR meets the contributing guidelines

    Considering #2537, the precision error can be fixed by using the combination of String.valueOf and BigDecimal.

    Following the contributing guidelines will make it easier for us to review and accept your PR.

    This pull request fixes the bug that offset with float[] assertion doesn't have the same behavior as offset with float assertion, which is the main topic of #2414.

    opened by YeeTone 33
  • Add method to use SoftAssertions with any custom Assertions

    Add method to use SoftAssertions with any custom Assertions

    Add static assertSoftly method to be able to use any common and custom assertion side by side within on assertSoftly call/scope e.g.

            SoftAssertions.assertSoftly(
                    () -> Assertions.assertThat("test1").isEqualTo("bar"),
                    () -> GuavaAssertions.assertThat(...).contains(...),
                    () -> MyAssertion.assertThat(...).contains(...)
            );
    

    Check List:

    • Unit tests : NO
    • Javadoc with a code example (API only) : NO
    opened by qoomon 28
  • Bytes assertions enhancements - better readability

    Bytes assertions enhancements - better readability

    My proposition for assertions arrays:

    assertThat("zólc".getBytes()).contains("żółć".getBytes("ISO-8859-2"));
    
    java.lang.AssertionError:
    Expecting:
    <[7A:C3:B3:6C:63]>
    to contain:
    <[BF:F3:B3:E6]>
    but could not find:
    <[BF:F3:E6]>
    

    This is more readable than:

    java.lang.AssertionError:
    Expecting:
    <[0x7A, 0xC3, 0xB3, 0x6C, 0x63]>
    to contain:
    <[0xBF, 0xF3, 0xB3, 0xE6]>
    but could not find:
    <[0xBF, 0xF3, 0xE6]>
    

    Simple values comparision without changes:

    assertThat((byte) 0xff).isEqualTo((byte) '3');
    
    org.junit.ComparisonFailure:
    Expected :0x33
    Actual   :0xFF
    

    What do you think?

    opened by mariuszs 28
  • Improve the performance of `containsExactly` from quadratic to linear complexity

    Improve the performance of `containsExactly` from quadratic to linear complexity

    Summary

    The performance of the containsExactly function of Iterables is currently quadratic, while it could be linear. It seems to be because of the IterableDiff class it uses, which checks the extra and missing elements with an algorithm suitable for checking the elements in any order. However, this is not necessary, since they have to be present in the exact order and so a more efficient linear solution could look something like this:

    boolean compare(expected, actual) {
        if (expected.size() != actual.size()) return false;
        for (int i = 0; i < expected.size(); i++) {
           if (expected.get(i) != actual.get(i)) return false;
        }
        return true;
    }
    

    We ran a scalability analysis on various assertions, which you can find here if you are interested.

    opened by sarajuhosova 27
  • Improve the way to assert exceptions

    Improve the way to assert exceptions

    This commit makes it possible to write things like this:

    assertThat((ExceptionalRunnable) () -> { 
        throw new IllegalArgumentException(); 
    }).toThrow(IllegalArgumentException.class);
    

    or on Java 7:

    assertThat(new ExceptionalRunnable() {
      @Override
      public void run() throws Exception {
        throw new IllegalArgumentException();
      }
    }).toThrow(IllegalArgumentException.class);
    

    instead of:

    try {
        throw new IllegalArgumentException();
        failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
    } catch (IllegalArgumentException ignored) {}
    
    opened by Turbo87 26
  • Ship Kotlin helper functions by default

    Ship Kotlin helper functions by default

    Feature summary

    There's a value in shipping Kotlin-friendly API by default.

    See https://github.com/junit-team/junit5/blob/main/junit-jupiter-api/src/main/kotlin/org/junit/jupiter/api/Assertions.kt

    For example, the current SoftAssertions syntax is

    SoftAssertions.assertSoftly { softly ->
        // ...
        softly.assertThat(...).isEqualTo(...)
        // ...
        softly.assertAll()
    }
    

    The issue is that it is verbose, and the user might fail to call assertAll.

    A better variation would be

    assertSoftly {
        assertThat(...).isEqualTo(...)
        // no need to call assertAll, it would be automatic
    }
    

    That is achievable with a small helper:

        fun assertSoftly(body: SoftAssertions.() -> Unit) {
            SoftAssertions().apply {
                body() // What if body() throws an exception? Should it be called and wrapped with a "assertnot throws"?
                assertAll()
            }
        }
    
    3rd-party: Kotlin 
    opened by vlsi 0
  • Remove generic return type from Assertions.fail and AbstractSoftAssert.fail

    Remove generic return type from Assertions.fail and AbstractSoftAssert.fail

    Describe the bug

    Kotlin compilation fails with Not enough information to infer type variable T

    • assertj core version: 3.23.1
    • Java version: 11
    • Kotlin: 1.7.21

    It looks like the only reason for adding a return type to fail was to use the failure in Optional.orElseGet, however, I believe that usage is NOT justified: https://github.com/assertj/assertj/commit/ce2dcef5ba64bb878aaa05339dc306767bb3d807

    The same goes for soft assertions: return type was added with no justification in https://github.com/assertj/assertj/issues/2094

    I believe, for Optional, a much better usage would be orElseThrow(Supplier<? extends X> exceptionSupplier).

    So I think it would be better to have:

    1. A fixed return type like Error rather than <T> T for regular assertions
    2. void return type for SoftAssertion. In other words, I believe 820d2927c11e0ddcd371c9de58b40f4245d66fdb should be reverted.

    The usage suggested in javadoc AbstractSoftAssertions.fail is unsafe:

    @return nothing, it's just to be used in {@code doSomething(optional.orElseGet(() -> fail("boom")));}.
    

    SoftAssertion does not really fail when fail(...) is executed, so orElseGet would return null, and doSomething method would fail with NPE.

    Test case reproducing the bug

    Kotlin code:

    Assertions.fail("this value is not supported yet ...") // <-- error here
    
    SoftAssertions.assertSoftly { softly ->
        softly.fail("test") // <-- error here
    }
    
    3rd-party: Kotlin theme: soft assertions 
    opened by vlsi 2
  • `isSameAs` fails with primitive type values outside of autobox cache

    `isSameAs` fails with primitive type values outside of autobox cache

    Describe the bug

    isSameAs assertions on primitive types fail if the value being tested is outside the cached range of the corresponding wrapper type.

    From JLS section 5.1.7:

    If the value p being boxed is an integer literal of type int between -128 and 127 inclusive (§3.10.1), or the boolean literal true or false (§3.10.3), or a character literal between '\u0000' and '\u007f' inclusive (§3.10.4), then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.

    Test case reproducing the bug

    assertThat(127 == 127).isTrue(); // succeeds
    assertThat(127).isSameAs(127);   // succeeds
    
    assertThat(128 == 128).isTrue(); // succeeds
    assertThat(128).isSameAs(128);   // fails
    
    type: bug 
    opened by scordio 1
  • Add if-else conditions

    Add if-else conditions

    Feature summary

    I think that it is convenient to add if-else functionality.

    Example

    If assertions depends on value of expectedId variable now I use code (example in Kotlin syntax):

    if (expectedId != null) {
        assertThat(id)
            .`as`("id")
            .isEqualTo(expectedId)
    
    } else {
        assertThat(id)
            .`as`("id")
            .isGreaterThan(0)
    }
    

    It's better to rewrite this code to remove duplication and improve readability as (it's possible to change if method name to when or smth else)

    assertThat(id)
        .`as`("id")
        .`if`(expectedId != null) {
            it.isEqualTo(expectedId)
        }
        .`else` {
            it.isGreaterThan(0)
        }
    

    Variant of implementation:

    class AbstractIntegerIfAssert<SELF: AbstractIntegerAssert<SELF>>(
        private val condition: Boolean,
        private val asset: AbstractIntegerAssert<SELF>
    ) {
        fun `else`(
            assertion: (AbstractIntegerAssert<SELF>) -> Unit
        ): AbstractIntegerAssert<SELF> {
            if (!condition) {
                assertion(asset)
            }
            return asset
        }
    
    }
    
    fun <SELF: AbstractIntegerAssert<SELF>> AbstractIntegerAssert<SELF>.`if`(
        condition: Boolean,
        assertion: (AbstractIntegerAssert<SELF>) -> Unit
    ): AbstractIntegerIfAssert<SELF> {
    
        if (condition) {
            assertion(this)
        }
    
        return AbstractIntegerIfAssert(condition, this)
    }
    

    This implementation provides the ability to use more complex if-else conditions too

    assertThat(id)
        .`as`("id")
        .`if`(expectedId != null) {
            it
                .isEqualTo(expectedId)
                .`if`(a == b){
                    ...
                }
        }
        .`else` {
            it.isGreaterThan(0)
        }
    
    opened by ars-java 2
  • Added Throwable Stacktrace to ShouldHaveCause

    Added Throwable Stacktrace to ShouldHaveCause

    Check List:

    • Fixes assertj/assertj/issues/1355
    • Unit tests : YES (no new)
    • Javadoc with a code example (on API only) : NO, no API changes involved
    • PR meets the contributing guidelines

    Following the contributing guidelines will make it easier for us to review and accept your PR.

    opened by Ds2994 0
  • isNull() throws NullPointerException on Java nullable type from a Kotlin test

    isNull() throws NullPointerException on Java nullable type from a Kotlin test

    Describe the bug

    When I have a Java class with a property nullable type Double. And from a Kotlin test I try to assert that property value with: assertThat(dataClass.nullableProperty).isNull()

    It will throw a: "java.lang.NullPointerException:class.nullableProperty must not be null"

    image image

    • assertj core version: 3.23.1
    • java version: 17
    • test framework version: JUnit 5.8.2

    Test case reproducing the bug

    Add a test case showing the bug that we can run

    package io.tbolier.test
    
    import org.assertj.core.api.Assertions.assertThat
    import org.junit.jupiter.api.Test
    
    class AssertJIssue {
        @Test
        fun assertNullablePropertyKotlin() {
            val dataClass = Data(null)
            assertThat(dataClass.nullableProperty).isNull()
        }
    
        @Test
        fun assertNullablePropertyJava() {
            val dataClass = JavaData(null)
            assertThat(dataClass.nullableProperty).isNull()
        }
    }
    
    data class Data(val nullableProperty: Double?)
    
    
    package io.tbolier.test
    record JavaData(Double nullableProperty) {}
    
    3rd-party: Kotlin 
    opened by tbolier 0
Fluent assertions library for Java

Deep Dive Assertions Deep Dive is an assertion library for Java. It offers a fluent API which allows you to dive deep, i.e. going back and forth betwe

Johannes Döbler 6 Jan 24, 2022
Fluent assertions for Java and Android

What is Truth? Truth makes your test assertions and failure messages more readable. Similar to AssertJ, it natively supports many JDK and Guava types,

Google 2.6k Jan 5, 2023
Never debug a test again: Detailed failure reports and hassle free assertions for Java tests - Power Asserts for Java

Scott Test Reporter for Maven and Gradle Get extremely detailed failure messages for your tests without assertion libraries, additional configuration

Dávid Csákvári 133 Nov 17, 2022
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

Testcontainers Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium we

null 6.7k Jan 9, 2023
JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.

pact-jvm JVM implementation of the consumer driven contract library pact. From the Ruby Pact website: Define a pact between service consumers and prov

Pact Foundation 962 Dec 31, 2022
Java DSL for easy testing of REST services

Testing and validation of REST services in Java is harder than in dynamic languages such as Ruby and Groovy. REST Assured brings the simplicity of usi

REST Assured 6.2k Dec 31, 2022
Easy Setup Stub Server

Moco Moco is an easy setup stub framework. Latest Release 1.1.0 More details in Release Notes User Voice Let me know if you are using Moco. Join Moco

Zheng Ye 4.1k Dec 30, 2022
Java DSL for easy testing of REST services

Testing and validation of REST services in Java is harder than in dynamic languages such as Ruby and Groovy. REST Assured brings the simplicity of usi

REST Assured 6.2k Dec 25, 2022
MockServer enables easy mocking of any system you integrate with via HTTP or HTTPS with clients written in Java, JavaScript and Rub

MockServer enables easy mocking of any system you integrate with via HTTP or HTTPS with clients written in Java, JavaScript and Ruby. MockServer also includes a proxy that introspects all proxied traffic including encrypted SSL traffic and supports Port Forwarding, Web Proxying (i.e. HTTP proxy), HTTPS Tunneling Proxying (using HTTP CONNECT) and SOCKS Proxying (i.e. dynamic port forwarding).

Mock-Server 4k Jan 4, 2023
JUnit 5 extension for easy-random

Easy Random/Faker JUnit 5 extension The simple, stupid random Java™ beans generator for JUnit 5 The easy random extension provides a test with randoml

Libing Chen 8 Nov 9, 2022
This repository contains example codes which will help you to know how to use selenium webdriver.

❓ What is this Repository about? This repo has example codes with Selenium 4 features. Websites used for testing are: automationpractice.com, saucedem

Mohammad Faisal Khatri 86 Dec 30, 2022
simple web3j Demo to be continue,use web3j Brainless Trading,tool for arbitrage automatic trading, copying other transfer,tracking agency addresses, setting profit points, setting prices, grabbing blocks

simple web3j Demo to be continue,use web3j Brainless Trading,tool for arbitrage automatic trading, copying other transfer,tracking agency addresses, setting profit points, setting prices, grabbing blocks

Nate River 262 Jan 7, 2023
Simple meteor addon to bypass other addons that use a uuid-based authentication system

Auth Bypass A Meteor Addon that automatically bypasses other addons using a uuid-based authentication system How to use: Download the latest release f

GhostTypes 4 Apr 1, 2022
Ready-to-use UI Test Automation Architecture using Java and Selenium WebDriver.

Selenium Test Automation Boilerplate Ready-to-use UI Test Automation Architecture using Java and Selenium WebDriver. Languages and Frameworks The proj

Tahanima Chowdhury 133 Dec 26, 2022
provides all the interfaces that AREX-UI needs to use

AREX-SERVICE This project provides all the interfaces that AREX-UI needs to use. QUICK START quick start API DOCUMENTS We use swagger3 to generate int

ArexTest 4 Dec 15, 2022
A sample repo to help you use relative locators for automation test in Java-TestNG on LambdaTest. Run Selenium tests with TestNG on LambdaTest platform.

How to use relative locators for automation test in Java-TestNG on LambdaTest Environment Setup Global Dependencies Install Maven Or Install Maven wit

null 11 Jul 13, 2022
A sample repo to help you use CDP console in Java-TestNG automation test on LambdaTest. Run Selenium tests with TestNG on LambdaTest platform.

How to use CDP console in Java-TestNG automation test on LambdaTest Environment Setup Global Dependencies Install Maven Or Install Maven with Homebrew

null 11 Jul 13, 2022
Library that allows tests written in Java to follow the BDD style introduced by RSpec and Jasmine.

J8Spec J8Spec is a library that allows tests written in Java to follow the BDD style introduced by RSpec and Jasmine. More details here: j8spec.github

J8Spec 45 Feb 17, 2022