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

时间:2016-01-20 18:16:21

标签: 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中的内容。我不确定这是否可以实现。可能有另一种更好的方法来解决这个问题。有人可以提出一些想法吗?

1 个答案:

答案 0 :(得分:0)

在您的测试中,您似乎正在使用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用mock(在MockitoJUnitRunner中)覆盖它。只是说:

。好多了
/* GOOD */
@Mock AnotherClass acObj;