栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在匿名类中测试方法时,如何使用Powermockito模拟新对象的构造?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在匿名类中测试方法时,如何使用Powermockito模拟新对象的构造?

信息很明显:您不能模拟不可见和最终类。简短答案: 创建一个 匿名 命名类 ,然后 测试该类

长答案,让我们找出原因吧!

匿名班是最终的

您实例化一个的匿名类

FilterFactory
,当编译器看到一个匿名类时,它将创建一个 最终的 ,可 打包的可见
类。因此,匿名类无法通过标准方式(即通过Mockito)进行嘲笑。

模拟匿名课程:可能,但如果不是HACKY,则为BRITTLE

好的,现在假设您希望能够通过Powermock模拟该匿名类。当前的编译器使用以下方案编译匿名类:

Declaring class + $ + <order of declaration starting with 1>

模拟匿名类是可能的,但又很脆弱(我是说真的)所以假设匿名类是第11个要声明的类,它将显示为

InputHelper$11.class

因此,您可以潜在地准备测试匿名类:

@RunWith(PowerMockRunner.class)@PrepareForTest({InputHelper$11.class})public class InputHelperTest {    @Test    public void anonymous_class_mocking works() throws Throwable {        PowerMockito.spy(InputHelper.BZIP2_FACTORY);  // This line fails    }}

该代码将被编译,但最终将在您的IDE中报告为错误。IDE可能不知道

InputHelper$11.class
。如此不使用编译类检查代码报告的IntelliJ。

同样,匿名类命名实际上取决于声明的顺序这一事实也是一个问题,当有人在之前添加另一个匿名类时,编号可能会更改。使匿名类保持匿名,如果编译人员决定某一天使用字母或什至随机标识符怎么办!

因此,通过Powermock模拟匿名类是可能的,但是很脆弱,永远不要在真实的项目中这样做!

编辑说明: Eclipse编译器具有不同的编号方案,它始终使用3位数字:

Declaring class + $ + <pad with 0> + <order of declaration starting with 1>

我也不认为JLS明确规定了编译器应如何命名匿名类。

您无需将间谍重新分配给静态字段

PowerMockito.spy(InputHelper.BZIP2_FACTORY);  // This line failswhenNew(BufferedInputStream.class).withArguments(in).thenReturn(buffer);whenNew(CBZip2InputStream.class).withArguments(buffer).thenReturn(expected);InputStream observed = InputHelper.BZIP2_FACTORY.makeFilter(in);

PowerMockito.spy
返回间谍,它不会更改的值
InputHelper.BZIP2_FACTORY
。因此,您将需要通过反射来实际设置此字段。您可以使用
Whitebox
Powermock提供的实用程序。

结论

仅用匿名过滤器使用的模拟进行测试就很麻烦

BufferedInputStream

另类

我宁愿编写以下代码:

使用命名类的输入助手,我不会使用接口名称来向用户表明此过滤器的目的!

public class InputHelper {    public static final BufferedBZIP2FilterFactory BZIP2_FACTORY = new BufferedBZIP2FilterFactory();}

现在过滤器本身:

public class BufferedBZIP2FilterFactory {    public InputStream makeFilter(InputStream in) {        BufferedInputStream buffer = new BufferedInputStream(in);        return new CBZip2InputStream(buffer);    }}

现在您可以编写这样的测试:

@RunWith(PowerMockRunner.class)public class BufferedBZIP2FilterFactoryTest {    @Test    @PrepareForTest({BufferedBZIP2FilterFactory.class})    public void wraps_InputStream_in_BufferedInputStream() throws Exception {        whenNew(CBZip2InputStream.class).withArguments(isA(BufferedInputStream.class))     .thenReturn(Mockito.mock(CBZip2InputStream.class));        new BufferedBZIP2FilterFactory().makeFilter(anInputStream());        verifyNew(CBZip2InputStream.class).withArguments(isA(BufferedInputStream.class));    }    private ByteArrayInputStream anInputStream() {        return new ByteArrayInputStream(new byte[10]);    }}

但是如果您强制

CBZip2InputStream
只接受,最终可以避免在此测试方案中使用powermock东西
BufferedInputStream
。通常使用Powermock意味着设计有问题。
在我看来,Powermock非常适合旧版软件,但在设计新代码时可能会使开发人员失明。
因为他们错过了OOP的优势,所以我什至会说他们正在设计遗留代码。

希望能有所帮助!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/496942.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号