【问题标题】:Mock call to outside method in javajava中对外部方法的模拟调用
【发布时间】:2023-03-19 11:59:01
【问题描述】:

我有一个关于如何在java中模拟一些调用的问题,例如,假设我有这个:

import whatever.package;

Class myClass extends otherClass {

    public void myMethod() {
        ...
        int a = methodCall();
        ...
    }
}

问题是“methodCall()”来自包“whatever.package”,它是从“otherClass”继承的。是否可以模拟它以返回我想要的任何 int?

非常感谢!!

【问题讨论】:

  • 那么methodCall在同一个类中?
  • “来自包装”是什么意思?它是myClass 或其他类的静态成员吗​​?还是myClass 的非静态成员?
  • 所以 methodCall() 来自另一个包,因此它是另一个对象/类的一部分。但是你把它当作 myClass 的一个方法来使用。那么是哪一个呢?它可以是静态的,但不是必须的。 ..在您的示例代码中指出所有这些,这对于这个问题非常重要。如果你不这样做,就像问“我有一辆车,它有一些零件,比如发动机和变速箱,但它不工作,我该如何修理?”
  • 绝对需要知道它是否是静态的。另外,如果它是非静态的,那么对象在哪里实例化?它是类级别的对象,还是特定于您的方法?
  • 我刚刚意识到您的 cmets 我没有提供太多信息,对此感到抱歉。该方法属于我可以使用但我无权访问的类,因为它是我不拥有的某些软件的一部分。该方法是从另一个类继承的,所以我想这是在模拟对你父母的一些调用,我刚刚在我的帖子中解决了这个问题。

标签: java methods mocking easymock powermock


【解决方案1】:

在cmets澄清后

如果它是继承的,您可以使用我提出的最后一个模式(测试扩展 myClass)并简单地覆盖 methodCall()


在这个答案中,我假设 methodCall() 是您拥有的另一个类的非静态方法。

让我们修改示例代码:

import whatever.package;

Class myClass 
{
    public void myMethod() 
    {
        ...
        anotherClass aClass = new anotherClass();
        int a = aClass.methodCall();
        ...
    }
}

所以,现在我们要模拟出另一个类的methodCall()。

正常的过程是使用接口并将“接线”推到其他地方,以避免紧密耦合。对依赖注入和类似概念进行一些研究。

简而言之,使用 new anotherClass() 会创建紧密耦合。您可以在 myClass 构造函数中或通过 getter 和 setter 注入 anotherClass 对象。我假设您需要模拟来编写单元测试。考虑以下代码:

import whatever.package;

Class myClass 
{
    private IanotherClass another;

    public void SetAnotherClass(IAnotherClass aClass)
    {
         another = aClass;
    }

    public void myMethod() 
    {
        ...
         int a = another.methodCall();
        ...
    }
}

测试代码:

   myClass testedClass = new myClass();
   testedClass.SetAnotherClass(new MyAnotherClassMock());
   testedClass.myMethod();

至于注入依赖项和针对接口而不是实现进行编程,关于该主题有很多要阅读的内容 - 只需 google 一下!

如果您不想重新设计整个代码并且只需要快速(并且有点脏)修复,您可以考虑将创建 anotherClass 实例移动到单独的方法中,然后简单地让您的测试类从您的类继承,覆盖提到方法(这并不总是可能的 - 完全取决于您的实际代码)

示例:

Class myClass 
{
    public void myMethod() 
    {
        ...
        IanotherClass aClass = GetAnotherClassInstance();
        int a = aClass.methodCall();
        ...
    }

    protected IanotherClass GetAnotherClassInstance()
    {
        return new anotherClass();
    }
}

Class MyTestClass extends myClass
{
   @overwrite
   protected IanotherClass GetAnotherClassInstance()
   {
        return new anotherClassMock();
   }
}

那么只需使用 myTestClass 进行测试!

【讨论】:

  • 是的,我不想更改我的代码来测试它,但看来我最终还是得这样做 :) 感谢您的回答!
【解决方案2】:

无需重新设计代码?

模拟methodCall的类并在classpathorder中向上推。

【讨论】:

  • 如何在classpathorder中上推?
  • 不确定,尝试将类复制到系统类路径应该适用于您的情况,即 c:/progr/java/jdk13456/jre/lib/rt.jar。
  • 在模拟测试后不要忘记从 rt.jar 中删除类
  • 见鬼,没人这样做!干净的嘲笑并不总是可能的。 , 模拟通常需要特定的代码设计
  • 我认为您应该在答案中写下这一点。人们会来到这里,看到你的答案,并相信应该这样做。我相信让 SO 有价值的最好方法是解决问题,而不是问题本身。人们通常会问如何对他们的问题实施糟糕的解决方案。我认为最好只为他们提供好的解决方案及其实施。
猜你喜欢
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多