【问题标题】:Mocking two maps in a class在一个类中模拟两个地图
【发布时间】:2017-11-07 10:40:58
【问题描述】:

我必须测试一个使用弹簧注入两个地图的类。 我想模拟两张地图。 我使用 Mock 符号如下:

@Mock
private Map<String, Integer> map1;

@Mock
private Map<String, Date> map2;

但我收到以下错误:

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Date

似乎只有第一个模拟地图用于两个地图。

我做错了什么?

【问题讨论】:

  • 为我工作。 Mockito 版本 1.10.19。有什么你没有给我们看的吗?

标签: java maps mockito


【解决方案1】:

只要两个字段的类型相同,mockito 不知道如何按类型注入您的模拟。所以它尝试按名称注入它。在这种情况下,您的测试类中的字段名称看起来与您创建的模拟对象不匹配。 这是@InjectMocksdoc

字段注入;模拟将首先按类型解析(如果单个 无论名称如何,类型匹配注入都会发生),那么,如果 有多个相同类型的属性,通过字段的匹配 名称和模拟名称。

您可以重命名您的文件或使用明确的模拟名称:

@Mock(name="foo")
private Map<String, Integer> map1;

@Mock(name="bar")
private Map<String, Date> map2;

但我不认为这是最好的解决方案。如果文件名被重命名,您将得到假阴性测试结果:功能正常但测试失败。

对我来说,最好的解决方案是重构您的代码,以便被测类在构造函数中接收依赖项。之后你可以像这样模拟它:

@Mock
private Map<String, Integer> map1;

@Mock
private Map<String, Date> map2;

private ClassUnderTets cut;

@Before
public void setUp() throws Exception {
    cut = new ClassUnderTets(map1, map2);
}

甚至:

@Mock
private Map<String, Integer> map1;

@Mock
private Map<String, Date> map2;

@InjectMocks
private ClassUnderTets cut;

如文档中所述:

构造函数注入;选择最大的构造函数,然后用 仅在测试中声明的模拟

【讨论】:

  • 感谢您的帮助,我已经在使用 InjectMocks 表示法,但它不起作用。当我用构造函数中的依赖项替换它时,它起作用了
【解决方案2】:

您可能遇到问题,因为您尝试注入两个具有相同接口的模拟(例如,变量名称与属性不匹配)

请查看此topic 的第二个帖子以供参考。

属性设置器注入;模拟将首先按类型解析,然后, 如果有多个相同类型的属性,则通过匹配 属性名称和模拟名称。

【讨论】:

  • 我用构造函数注入了地图,而不是像第二篇文章中推荐的那样使用“InjectMocks”表示法,它起作用了。我真的不明白为什么 InjectMocks 在我的情况下不起作用。
【解决方案3】:

试试

@Mock
private Map map1;

@Mock
private Map map2;

改为

@Mock
private Map<String, Integer> map1;

@Mock
private Map<String, Date> map2;

然后你只需要模拟如下行为:

when(map1).get("hello").thenReturn(25);
when(map2).get("birthday").thenReturn(new Date(2000, 07, 24));

【讨论】:

    猜你喜欢
    • 2014-04-03
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 2014-08-13
    • 2021-12-17
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多