Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add doesNotReturn to Object assertions #2453

Merged
merged 1 commit into from Dec 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 28 additions & 1 deletion src/main/java/org/assertj/core/api/AbstractObjectAssert.java
Expand Up @@ -654,7 +654,8 @@ public SELF hasFieldOrProperty(String name) {
* <p>
* Private fields are matched by default but this can be changed by calling {@link Assertions#setAllowExtractingPrivateFields(boolean) Assertions.setAllowExtractingPrivateFields(false)}.
* <p>
* If you are looking to chain multiple assertions on different properties in a type safe way, consider chaining {@link #returns(Object, Function)} calls.
* If you are looking to chain multiple assertions on different properties in a type safe way, consider chaining
* {@link #returns(Object, Function)} and {@link #doesNotReturn(Object, Function)} calls.
* <p>
* Example:
* <pre><code class='java'> public class TolkienCharacter {
Expand Down Expand Up @@ -1093,6 +1094,32 @@ public <T> SELF returns(T expected, Function<ACTUAL, T> from) {
return myself;
}

/**
* Verifies that the object under test does not return the given expected value from the given {@link Function},
* a typical usage is to pass a method reference to assert object's property.
* <p>
* Wrapping the given {@link Function} with {@link Assertions#from(Function)} makes the assertion more readable.
* <p>
* Example:
* <pre><code class="java"> // from is not mandatory but it makes the assertions more readable
* assertThat(frodo).doesNotReturn("Bilbo", from(TolkienCharacter::getName))
* .doesNotReturn("Bilbo", TolkienCharacter::getName) // no from :(
* .doesNotReturn(null, from(TolkienCharacter::getRace));</code></pre>
*
* @param expected the value the object under test method's call should not return.
* @param from {@link Function} used to acquire the value to test from the object under test. Must not be {@code null}
* @param <T> the expected value type the given {@code method} returns.
* @return {@code this} assertion object.
* @throws NullPointerException if given {@code from} function is null
*
* @since 3.22.0
*/
public <T> SELF doesNotReturn(T expected, Function<ACTUAL, T> from) {
requireNonNull(from, "The given getter method/Function must not be null");
objects.assertNotEqual(info, from.apply(actual), expected);
return myself;
}

/**
* Enable using a recursive field by field comparison strategy when calling the chained {@link RecursiveComparisonAssert#isEqualTo(Object) isEqualTo} assertion.
* <p>
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/assertj/core/api/Assertions.java
Expand Up @@ -2211,13 +2211,14 @@ public static TemporalUnitOffset byLessThan(long value, TemporalUnit unit) {
}

/**
* A syntax sugar to write fluent assertion using {@link ObjectAssert#returns(Object, Function)}.
* A syntax sugar to write fluent assertion using {@link ObjectAssert#returns(Object, Function)} and
* {@link ObjectAssert#doesNotReturn(Object, Function)}.
* <p>
* Example:
* <pre><code class="java"> Jedi yoda = new Jedi("Yoda", "Green");
* assertThat(yoda).returns("Yoda", from(Jedi::getName))
* .returns(2.4, from(Jedi::getHeight))
* .returns(150, from(Jedi::getWeight)); </code></pre>
* .doesNotReturn(null, from(Jedi::getWeight)); </code></pre>
*
* @param extractor A function to extract test subject's property
* @param <F> Type of test subject
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/assertj/core/api/BDDAssertions.java
Expand Up @@ -2601,13 +2601,14 @@ public static TemporalUnitOffset byLessThan(long value, TemporalUnit unit) {
}

/**
* A syntax sugar to write fluent assertion using {@link ObjectAssert#returns(Object, Function)}.
* A syntax sugar to write fluent assertion using {@link ObjectAssert#returns(Object, Function)} and
* {@link ObjectAssert#doesNotReturn(Object, Function)}.
* <p>
* Example:
* <pre><code class="java"> Jedi yoda = new Jedi("Yoda", "Green");
* assertThat(yoda).returns("Yoda", from(Jedi::getName))
* .returns(2.4, from(Jedi::getHeight))
* .returns(150, from(Jedi::getWeight)); </code></pre>
* .doesNotReturn(null, from(Jedi::getWeight)); </code></pre>
*
* @param extractor A function to extract test subject's property
* @param <F> Type of test subject
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/assertj/core/api/WithAssertions.java
Expand Up @@ -1772,13 +1772,14 @@ default TemporalUnitOffset byLessThan(long value, TemporalUnit unit) {
}

/**
* A syntax sugar to write fluent assertion using {@link ObjectAssert#returns(Object, Function)}.
* A syntax sugar to write fluent assertion using {@link ObjectAssert#returns(Object, Function)} and
* {@link ObjectAssert#doesNotReturn(Object, Function)}.
* <p>
* Example:
* <pre><code class="java"> Jedi yoda = new Jedi("Yoda", "Green");
* assertThat(yoda).returns("Yoda", from(Jedi::getName))
* .returns(2.4, from(Jedi::getHeight))
* .returns(150, from(Jedi::getWeight)); </code></pre>
* .doesNotReturn(null, from(Jedi::getWeight)); </code></pre>
*
* @param extractor A function to extract test subject's property
* @param <F> Type of test subject
Expand Down
@@ -0,0 +1,56 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* Copyright 2012-2021 the original author or authors.
*/
package org.assertj.core.api.object;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.assertj.core.api.Assertions.from;
import static org.assertj.core.api.BDDAssertions.then;
import static org.mockito.Mockito.verify;

import org.assertj.core.api.ObjectAssert;
import org.assertj.core.api.ObjectAssertBaseTest;
import org.assertj.core.test.Jedi;
import org.junit.jupiter.api.Test;

class ObjectAssert_doesNotReturn_Test extends ObjectAssertBaseTest {

@Override
protected ObjectAssert<Jedi> invoke_api_method() {
return assertions.doesNotReturn("Yoda", Jedi::getName);
}

@Override
protected void verify_internal_effects() {
verify(objects).assertNotEqual(getInfo(assertions), getActual(assertions).getName(), "Yoda");
}

@Test
void should_fail_with_throwing_NullPointerException_if_method_is_null() {
// WHEN
Throwable thrown = catchThrowable(() -> assertions.doesNotReturn("May the force be with you.", null));
// THEN
then(thrown).isInstanceOf(NullPointerException.class)
.hasMessage("The given getter method/Function must not be null");
}

@Test
void perform_assertion_like_users() {
// GIVEN
Jedi yoda = new Jedi("Yoda", "Green");
// WHEN/THEN
assertThat(yoda).doesNotReturn("Luke", from(Jedi::getName))
.doesNotReturn("Luke", Jedi::getName);
}

}
Expand Up @@ -13,22 +13,17 @@
package org.assertj.core.api.object;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.assertj.core.api.Assertions.from;
import static org.assertj.core.api.BDDAssertions.then;
import static org.mockito.Mockito.verify;

import java.util.function.Function;

import org.assertj.core.api.AbstractObjectAssert;
import org.assertj.core.api.ObjectAssert;
import org.assertj.core.api.ObjectAssertBaseTest;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.assertj.core.test.Jedi;
import org.junit.jupiter.api.Test;

/**
* Tests for <code>{@link AbstractObjectAssert#returns(Object, Function)}</code>.
*
* @author Takuya "Mura-Mi" Murakami
*/
class ObjectAssert_returns_Test extends ObjectAssertBaseTest {
Expand All @@ -45,17 +40,20 @@ protected void verify_internal_effects() {

@Test
void should_fail_with_throwing_NullPointerException_if_method_is_null() {
ThrowingCallable code = () -> assertions.returns("May the force be with you.", null);
assertThatThrownBy(code).isExactlyInstanceOf(NullPointerException.class)
.hasMessage("The given getter method/Function must not be null");
// WHEN
Throwable thrown = catchThrowable(() -> assertions.returns("May the force be with you.", null));
// THEN
then(thrown).isInstanceOf(NullPointerException.class)
.hasMessage("The given getter method/Function must not be null");
}

@Test
void perform_assertion_like_users() {

// GIVEN
Jedi yoda = new Jedi("Yoda", "Green");
// WHEN/THEN
assertThat(yoda).returns("Yoda", from(Jedi::getName))
.returns("Yoda", Jedi::getName);

}

}