【问题标题】:How to mock System class? [duplicate]如何模拟系统类? [复制]
【发布时间】:2020-09-13 00:54:32
【问题描述】:

我正在尝试更改 System.currentTimeMillis() 方法的行为以进行测试。我找到了下面的方法,但是我不能在代码中使用 aspect 关键字。我真的不明白如何使用这种方法。有什么建议吗?

public aspect CurrentTimeInMillisMethodCallChanger {
    long around():
        call(public static native long java.lang.System.currentTimeMillis()) 
               && within(user.code.base.pckg.*) {
            return 0; // provide your own implementation returning a long
        }
}

查看related answer了解更多详细信息,包含上述代码的源代码

【问题讨论】:

  • 这段代码依赖于AspectJ,这是一个面向方面编程的Java库(Baeldung有一个good introduction to it)。仅出于模拟静态方法的目的,这有点矫枉过正,因此在您的情况下我不推荐它。
  • 这个方法应该适用于 AspectJ,加载时和编译时编织。而不是只引用其他答案,您应该解释您尝试了什么以及什么不起作用。你读过 AspectJ 的介绍吗?事实上,这个问题还不清楚,这就是为什么你已经获得了两张接近的选票。你应该改进它。
  • @kriegaex 我想这确实不是一个很好的问题。如何关闭它?
  • 对于投票认为这是重复的人:我不这么认为,因为问题是关于 AspectJ,而不是关于 PowerMock(ito)。并且即使你使用 PowerMock,请注意 System.currentTimeMillis() 是一个 native 方法,即它不能被字节码修改直接模拟。唯一可能的是在调用该方法的所有地方检测代码(我知道,PowerMock 也可以这样做)。这也是它与 AspectJ 一起使用的原因,使用 call() 切入点,而不是 execution()

标签: java aspectj aspect


【解决方案1】:

不要。如果您需要在特定时间进行测试,请不要在代码中使用System.currentTimeMillis(),而是使用Clock

这种抽象的主要目的是允许在需要时插入备用时钟。应用程序使用对象而不是静态方法来获取当前时间。这可以简化测试。

【讨论】:

  • 问题是我有一个退出复杂的集成测试,我不能模拟使用 System.currentTimeMillis() 方法的对象。如果我要使用时钟,我仍然无法更改它。
  • @DinuNicolae 如果您无法确定时间,则必须更改测试以使用实际时间。这使它们更难编写且可重复性降低。为可测试性设计代码很重要。
  • 我猜你是对的,测试不是很好的设计。
猜你喜欢
  • 2014-10-23
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多