如何将方法注入到java测试类中?

如何将方法注入到java测试类中?,java,unit-testing,reflection,junit,Java,Unit Testing,Reflection,Junit,如何在不扩展测试类的情况下将方法(使用反射)注入到超类中? 我需要替换getExternalData()来测试someMethod()中的逻辑。我不能改变被测试的类——因为我在考虑注入方法 我有流动课程: public class B extends A{ public String someMethod(){ String someString = super.getExternalData(); //logic to be tested - manipulating on

如何在不扩展测试类的情况下将方法(使用反射)注入到超类中?
我需要替换
getExternalData()
来测试
someMethod()中的逻辑。我不能改变被测试的类——因为我在考虑注入方法

我有流动课程:

public class B extends A{
  public String someMethod(){
    String someString = super.getExternalData();
    //logic to be tested - manipulating on someString
    return someString;
  }
}

public class A{
  public String getExternalData(){
    //some Logic that generates "externalData" string
    return externalData;
  }
}
和测试:

public class CesTest{
  @Test
  public void someMethodTest()(
    B instance = new B();
    //...
    //...
    assertEquals("expectedData", instance.someMethod());
  }
}

简单的回答是,如果不做一些非常奇怪的事情,你就不能不测试被测试的类,而是测试被测试类的一些奇怪的模拟版本。您需要执行所需的任何设置,以使
getExternalData
返回适当的值。这就是说,
A类
应该以这样的方式编写,即可以注入
模拟
来提供此
外部数据
,而无需访问外部资源。

为什么要使用

super.getExternalData()
不仅仅是

getExternalData()
这将允许您扩展B并覆盖getExternalData()

这对你有帮助吗?

(sry关于我的英语)

嗨,玛辛

我在4月11日10:55回答了你,但是,在我上完初中课后,如果你还没有解决问题,我有一个更好的解决方案:

首先,按照约定,TestClass必须使用sufix“Test”(在您的示例中为BTest)调用为SUT(受测主题)

其次,在JUnit中,经常使用模拟类来更改Collaborator方法(Collaborator是导致SUT依赖性的类)。更好的选择是使用Google代码的Mockito,这是一个免费的、更好的jUnit API。使用以下命令:

public class BTest{
  @Test
  public void someMethod()(
    B instance = new B();
    when(instance.getExternalData()).thenReturn("expectedData");
    assertEquals("expectedData", instance.someMethod());
  }
}

谷歌代码规则!如果可以,请投票给我的答案,谢谢

可能的重复:这是类的编写方式,不能更改代码-只需编写单元测试。在这种情况下,您必须使用AOP或反射。不管怎样,它都会很脏。这就是为什么我们说“如果你不能测试它-你的设计有问题”,你能扩展你的评论吗?在这种情况下如何使用反射或AOP?比如@Boris Pavlović说:我不能更改测试类——因为我在考虑注入方法。扩展B类是有选择的,但如果可能的话,我想避免这种情况
public class BTest{
  @Test
  public void someMethod()(
    B instance = new B();
    when(instance.getExternalData()).thenReturn("expectedData");
    assertEquals("expectedData", instance.someMethod());
  }
}