验证是否调用了所有 getter 方法

Verify that all getter methods are called(验证是否调用了所有 getter 方法)
本文介绍了验证是否调用了所有 getter 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我有以下测试,我需要验证是否调用了 Person 类的所有 getter.到目前为止,我已经使用了 mockito 的 verify() 来确保调用每个 getter.有没有办法通过反思来做到这一点?可能会在 Person 类中添加一个新的 getter,但测试会错过它.

I have the following test where I need to verify that all getters of the Person class are being called. So far I have used mockito's verify() to make sure that each getter is called. Is there a way to do that by reflection? It can be the case that a new getter is added to the Person class but the test will miss that.

public class GetterTest {
    class Person{

        private String firstname;
        private String lastname;

        public String getFirstname() {
            return firstname;
        }

        public String getLastname() {
            return lastname;
        }
    }

    @Test
    public void testAllGettersCalled() throws IntrospectionException{
        Person personMock = mock(Person.class);
        personMock.getFirstname();
        personMock.getLastname();

        for(PropertyDescriptor property : Introspector.getBeanInfo(Person.class).getPropertyDescriptors()) {
            verify(personMock, atLeast(1)).getFirstname();
            //**How to verify against any getter method and not just getFirstName()???**
        }
    }
}

推荐答案

一般情况下,不要模拟被测类.如果您的测试是针对 Person 的,那么您永远不会在其中看到 Mockito.mock(Person.class),因为这是一个非常明显的迹象,表明您正在测试模拟框架而不是系统- 正在测试中.

Generally, don't mock the class under test. If your test is for a Person, you shouldn't ever see Mockito.mock(Person.class) in it, as that's a pretty clear sign that you're testing the mocking framework instead of the system-under-test.

相反,您可能想要创建一个 spy(new Person()),它将使用真正的构造函数创建一个真正的 Person 实现,然后将其数据复制到 Mockito 生成的代理.您可以使用 MockingDetails.getInvocations() 反射性地检查是否调用了每个 getter.

Instead, you may want to create a spy(new Person()), which will create a real Person implementation using a real constructor and then copy its data to a Mockito-generated proxy. You can use MockingDetails.getInvocations() to reflectively check that every getter was called.

// This code is untested, but should get the point across. Edits welcome.
// 2016-01-20: Integrated feedback from Georgios Stathis. Thanks Georgios!

@Test
public void callAllGetters() throws Exception {
  Person personSpy = spy(new Person());
  personSpy.getFirstname();
  personSpy.getLastname();

  assertAllGettersCalled(personSpy, Person.class);
}

private static void assertAllGettersCalled(Object spy, Class<?> clazz) {
  BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
  Set<Method> setOfDescriptors = beanInfo.getPropertyDescriptors()
      .stream()
      .map(PropertyDescriptor::getReadMethod)
      .filter(p -> !p.getName().contains("getClass"))
      .collect(Collectors.toSet());
  MockingDetails details = Mockito.mockingDetails(spy);
  Set<Method> setOfTestedMethods = details.getInvocations()
      .stream()
      .map(InvocationOnMock::getMethod)
      .collect(Collectors.toSet());
  setOfDescriptors.removeAll(setOfTestedMethods);
  // The only remaining descriptors are untested.
  assertThat(setOfDescriptors).isEmpty();
}

可能有一种方法可以在 Mockito 生成的间谍上调用 verifyinvoke,但这似乎非常脆弱,并且非常依赖于 Mockito 内部结构.

There might be a way to call verify and invoke on the Mockito-generated spy, but that seems very fragile, and very dependent on Mockito internals.

顺便说一句,测试 bean 样式的 getter 似乎是对时间/精力的一种奇怪使用.一般来说,重点是测试可能会更改或中断的实现.

As an aside, testing bean-style getters seems like an odd use of time/effort. In general focus on testing implementations that are likely to change or break.

这篇关于验证是否调用了所有 getter 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How to send data to COM PORT using JAVA?(如何使用 JAVA 向 COM PORT 发送数据?)
How to make a report page direction to change to quot;rtlquot;?(如何使报表页面方向更改为“rtl?)
Use cyrillic .properties file in eclipse project(在 Eclipse 项目中使用西里尔文 .properties 文件)
Is there any way to detect an RTL language in Java?(有没有办法在 Java 中检测 RTL 语言?)
How to load resource bundle messages from DB in Java?(如何在 Java 中从 DB 加载资源包消息?)
How do I change the default locale settings in Java to make them consistent?(如何更改 Java 中的默认语言环境设置以使其保持一致?)