首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mockito如何处理供应商?

Mockito如何处理供应商?
EN

Stack Overflow用户
提问于 2021-09-06 20:03:52
回答 1查看 279关注 0票数 0

在第一张截图中,你可以看到我的测试课。这个类使用@ExtendWith({MockitoExtension.class})进行注释,并且测试的服务也使用@InjectMocks进行注释。在第二个屏幕截图中,您可以看到经过测试的服务。

为什么Mockito在这两种情况下都使用长供应商?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-07 03:51:27

Mockito在按以下顺序注入模拟时使用不同的战略

  1. 构造器注入
  2. 属性设置器注入
  3. 场注入

字段注入在您的示例中不起作用,因为服务的字段被声明为final

由于字段被声明为final,而且您展示的代码片段没有字段初始化器,所以我假设您有一个带有Supplier are的构造函数。例如。

代码语言:javascript
复制
public SomeService(Supplier<String> stringSupplier, Supplier<Long> longTimeSupplier) {
    this.stringSupplier = stringSupplier;
    this.longTimeSupplier = longTimeSupplier;
}

因此,Mockito将尝试构造函数注入,找到带有两个Supplier参数的构造函数,并尝试解析参数。

然后,Mockito在测试中找到两个Supplier模拟,但是由于类型擦除,它无法看到泛型类型。因此,Mockito看到构造函数如下:

代码语言:javascript
复制
public SomeService(Supplier stringSupplier, Supplier longTimeSupplier)

Mockito也不能根据参数名称来决定使用哪个Supplier,因为普通的Java没有提供这些信息。因此,模仿者的名字将不会被考虑在内。

偏执狂这样的库可以读取字节码并提取调试信息来读取参数名,但是Mockito不使用这个库。

因此,Mockito只是注入第一个匹配的模拟,在您的例子中是Supplier<String> stringSupplier。即使您的问题与泛型相关,当您有两个非泛型的相同类型的参数时,Mockito也会采取相同的方式。

我假设您有一个构造函数,它接受两个Supplier。所以你可以在测试之前调用它。

代码语言:javascript
复制
@BeforeEach
public void setup() {
    service = new SomeService(stringSupplier, longSupplier);
}

如果不能访问构造函数(例如,它有包作用域),则需要使用反射调用它,并将可访问属性设置为true

代码语言:javascript
复制
@BeforeEach
public void setup() throws Exception {
    Constructor<SomeService> constructor = SomeService.class.getConstructor(Supplier.class, Supplier.class);
    constructor.setAccessible(true);
    service = constructor.newInstance(stringSupplier, longSupplier);
}

如果要删除PS,请确保模拟是以服务longTimeSupplier vs. longSupplier中的字段命名的,或者使用@Mock(name = "longTimeSupplier")

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69079787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档