官术网_书友最值得收藏!

  • Mockito Cookbook
  • Marcin Grzejszczak
  • 545字
  • 2021-07-16 11:35:01

Creating mocks with different default answers with annotations

In the previous recipe, you have seen how to pass an implementation of the Answer interface to your mock to change its default behavior. In this recipe, we will focus on doing the same when creating mocks using annotations.

All versions of Mockito up until version 1.9.5 allow you to pass only elements of the Answers enum that delegate to answers present in the public Mockito API, as the arguments of the annotation. In the next Mockito release, there should be a possibility of passing a custom answer too, but until then it's not possible to do that.

Getting ready

In the following code, our system is a class that, based on the person's country, collects his Internal Revenue Service (IRS) address and formats it properly:

public class TaxFactorInformationProvider {

    private final TaxService taxService;

    public TaxFactorInformationProvider(TaxService taxService) {
        this.taxService = taxService;
    }

    public String formatIrsAddress(Person person) {
        String irsAddress = taxService.getInternalRevenueServiceAddress(person.getCountryName());
        return "IRS:[" + irsAddress + "]";
    }

}

Let's now write a test for the system that will check whether the address will be properly formatted if the IRS address is an empty string. We will create a stub of TaxService and stub its behavior (we don't want it to send any real requests).

How to do it...

If you want to pass a nondefault answer to the @Mock annotated field you have to set the answer property with a proper value of the Answers enum on the @Mock annotation.

Now, let's take a look at the test written for JUnit. For the TestNG configuration, please refer to Chapter 1, Getting Started with Mockito (I'm using the BDDMockito.given(...) and AssertJ's BDDAssertions.then(...) static methods. Check out Chapter 7, Verifying Behavior with Object Matchers, on how to work with AssertJ or how to do the same with Hamcrest's assertThat(...)).

@RunWith(MockitoJUnitRunner.class)
public class TaxFactorInformationProviderTest {

    @Mock(answer = Answers.RETURNS_SMART_NULLS) TaxService taxService;

    @InjectMocks TaxFactorInformationProvider systemUnderTest;

    @Test
    public void should_calculate_mean_tax_factor() {
        // when
        String parsedIrsAddress = systemUnderTest.formatIrsAddress(new Person());

        // then
        then(parsedIrsAddress).isEqualTo("IRS:[]");
    }

}

By passing Answers.RETURNS_SMART_NULLS, we've managed to define that if an unstubbed method returns a string, then from now on it will return an empty string by default. In that way, at the end, we get an empty value of the address.

How it works...

When the Mockito's MockitoJUnitRunner runner logic is executed at the end of the day, it calls the MockitoAnnotations.initMocks method. That is where the default AnnotationEngine is used, which, if not overriden in the global Mockito configuration, is InjectingAnnotationEngine. This engine delegates the processing of annotated elements to the DefaultAnnotationEngine that has different FieldAnnotationProcessors for different types of Mockito-related annotations. In this case, the MockAnnotationProcessor is called, which instantiates a MockSettings object on which the code calls methods matching the annotation parameters, such as extraInterfaces(...), name(...), and defaultAnswer(...). In the previous example, the ReturnsSmartNulls answer coming from the passed Answers.RETURNS_SMART_NULLS was passed to the aforementioned defaultAnswer(...) method of MockSettings. That is why the code eventually behaves as we expected it to.

See also

  • Refer to Chapter 1, Getting Started with Mockito, for additional information on the annotation-based Mockito configuration for both TestNG and JUnit
  • Refer to Chapter 4, Stubbing Behavior of Mocks, to see how to stub the mock's method so that they return custom answers
主站蜘蛛池模板: 措勤县| 达尔| 武乡县| 巴林左旗| 邢台县| 泸水县| 建瓯市| 子洲县| 济阳县| 凤冈县| 甘德县| 依安县| 株洲县| 永寿县| 平谷区| 乐平市| 开原市| 丹江口市| 马山县| 饶平县| 米林县| 南丹县| 闽清县| 郯城县| 安溪县| 林甸县| 修水县| 呼伦贝尔市| 秭归县| 孝昌县| 安平县| 孟津县| 日照市| 永吉县| 泸西县| 阿拉善右旗| 克拉玛依市| 两当县| 灵川县| 永清县| 凤冈县|