java - 如何让单元测试每次看到正在执行的java项目中的某个函数时都执行特定的测试用例?

标签 java unit-testing mockito

我在对 java 项目运行大量单元测试时遇到构建失败问题。我收到 NoClassDefFoundError 错误,这是因为单元测试缺乏获取依赖项的能力。我试图模拟该类的对象,然后调用该函数,但代码的结构方式对我来说处理这个问题变得有点复杂。我对单元测试非常陌生。我在下面提供了我的项目的代码结构示例

Class ServiceProvider(){

   obj declarations;

   public void mainFunction(){

       //Does a couple of things and calls a function in another class
       boolean val = subFunction();
  }           

  public boolean subFunction(){ 
       boolean val = AnotherClass.someFunction(text); 
       //this function throws lots of exceptions and all those are caught and handled 
       return val;
  }


@RunsWith(MockitoJUnitRunner.class)
Class UnitTestBunch(){

@Mock
AnotherClass acObj = new AnotherClass();

@InjectMock
ServiceProvider sp = new ServiceProvider();

@Test
public void unitTest1() throws Exception{

   when(acObj.someFunction(text)).thenReturn(true);

}

@Test
public void unitTest2() throws Exception{

    thrown.expect(ExceptionName.Class);
    sp.mainFunction();
}

我有一个使用模拟对象并执行与该类关联的函数调用的测试。但是,这里的问题是,有许多其他单元测试用例的编写方式与 unitTest2 函数类似,并且在测试结束时调用 mainFunction。此 mainFunction 调用 someFunction() 并导致 NoCalssDefFoundError()。我试图让单元测试每次看到 AnotherClass.someFunction() 时都执行 unitTest1 中的内容。我不确定这是否可以实现。可能还有另一种更好的方法来解决这个问题。有人可以提出一些想法吗?

最佳答案

在您的测试中,您似乎使用 unitTest1 进行设置,而不是用于测试任何内容。当您运行单元测试时,每个测试应该能够以任何顺序单独或一起运行。

您在测试中使用 JUnit4,因此将 unitTest1 中的语句添加到 @Before 方法中会非常容易。 JUnit4将在每个测试方法之前调用此方法(用@Test注释)。

@Before
public void stubAcObj() throws Exception{
  when(acObj.someFunction(text)).thenReturn(true);
} 

该方法可以命名为任何名称,尽管 setUp() 是从 JUnit3 中要重写的方法借用的通用名称。但是,它必须使用 org.junit.Before 进行注释。

如果您需要从多个测试用例中获得此信息,则只需创建一个帮助程序,就像使用任何代码一样。这对于 @InjectMocks 效果不佳,但您通常可能希望避免使用 @InjectMocks,因为如果您向被测系统添加依赖项,它会默默失败。

public class AnotherClassTestHelper {
  /** Returns a Mockito mock of AnotherClass with a stub for someFunction. */
  public static AnotherClass createAnotherClassMock() {
    AnotherClass mockAnotherClass = Mockito.mock(AnotherClass.class);
    when(mockAnotherClass.someFunction(text)).thenReturn(true);
    return mockAnotherClass;
  }
}
<小时/>

顺便说一句,这是一种违反直觉的模式:

/* BAD */
@Mock
AnotherClass acObj = new AnotherClass();

您创建一个新的、真正的 AnotherClass,然后指示 Mockito 用模拟覆盖它(在 MockitoJUnitRunner 中)。最好直接说:

/* GOOD */
@Mock AnotherClass acObj;

关于java - 如何让单元测试每次看到正在执行的java项目中的某个函数时都执行特定的测试用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34907520/

相关文章:

java - 变量在基本 Java 类中不可见

ruby - 如何对严重依赖于其他类的类进行单元测试?

android - 找不到 Mockito 和 JUnit

java - 如何使用 JUnit 5 测试调用 Instant.now() 的代码?

python - 单线程的 ZeroMQ 进程间通信丢失消息

java - Mockito 和 PowerMock MethodNotFoundException 被抛出

java - Java 中的 vector - Yahtzee 游戏

java - 大十进制周期数

java - 通过 itext(java) 在 pdf 中显示多语言字符

java - 如何使用 Mockito 模拟方法调用