测试ClassNotFound异常

时间:2016-04-19 09:58:19

标签: java android unit-testing junit4

我试图测试Android上的UnitTest找不到类。

发生了什么:
 1.我正在编写一个具有transitive依赖关系的android库,这些依赖关系在宿主应用程序中得到解决  2.开发人员可能会删除一些依赖项,例如删除所有com.example.package  3.我有一个工厂,它将尝试实例化(使用反射)一个Object并捕获ClassNotFoundException。如果开发人员删除了依赖项,则应抛出异常  4.我想测试这个案例,但我发现的只是依赖关系的问题,而不是如何测试它。

我想测试的示例代码

try {
    sNetworkResponseBuilderClass = OkHttpNetworkResponse.Builder.class;
} catch (Exception e){
    // <<<< I want to test this case
    new ClassNotFoundException("Unable to find OkHttpNetworkResponse.Builder.class").printStackTrace();
    return null;
}

使用的库: hamcrast,mockito,JUnit 4.

你知道怎么做吗?

7 个答案:

答案 0 :(得分:10)

所以对我而言,你需要做的第一件事是提取可以抛出public Class<? extends NetworkResponseBuilder> getNetworkResponseBuilderClass() throws ClassNotFoundException { // Your logic here } 的代码部分,以便能够轻松地模拟它,例如:

Mockito.spy

然后,您可以使用getNetworkResponseBuilderClass()测试实际工厂实例,以便能够重新定义方法public void testFactoryIfNetworkResponseBuilderNotFound() { Factory factory = spy(new Factory()); when(factory.getNetworkResponseBuilderClass()).thenThrow( new ClassNotFoundException() ); // The rest of your test here } public void testFactoryIfNetworkResponseBuilderFound() { Factory factory = spy(new Factory()); when(factory.getNetworkResponseBuilderClass()).thenReturn( OkHttpNetworkResponse.Builder.class ); // The rest of your test here } 的行为,如下所示:

{{1}}

有关Mockito.spy的更多详情。

答案 1 :(得分:6)

我不确定我是否正确理解了您的问题,但如果抛出异常,您可以查看JUnit:

@Test(expected=ClassNotFoundException.class)
public void testClassNotFoundException() {
    // a case where the exception gets thrown
}

答案 2 :(得分:3)

OkHttpNetworkResponse.Builder 可能如下:

package com.example.model;

public class OkHttpNetworkResponse {
    public static class Builder {

    }
}
  
      
  1. 我有一个Factory,它将尝试实例化(使用反射)一个Object并捕获ClassNotFoundException。如果开发人员删除   依赖项,应该抛出异常。
  2.   

工厂类:将创建任何对象,如下所示:

package com.example.factory;

public class Factory {
    public static Object getInstance(String className)
            throws ClassNotFoundException, InstantiationException,
            IllegalAccessException {
        Class clazz = Class.forName(className);
        return clazz.newInstance();
    }
}
  
      
  1. 开发人员可能会删除一些依赖项,例如“删除所有com.example.package”
  2.   
  3. 我想测试一下这个案例,但我发现的只是依赖项问题,而不是如何测试它。
  4.   

FactoryTest类:将测试是否抛出ClassNotFoundException可能如下所示:N.B:请仔细检查注释。

package com.example.factory;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

public class FactoryTest {
    Factory factory;

    @Test(expected=ClassNotFoundException.class)
    public void test() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        ClassLoader loader = FactoryTest.class.getClassLoader();
        String directory = loader.getResource(".").getPath() + "/com/example/model";
        File dir = new File(directory);
        //Checking directory already existed or not..
        assertTrue("Directory:"+dir.getPath()+" not exist",dir.exists());
          //Deleting directory 
        deleteDirectoryProgramatically(directory);
        //Checking directory already deleted or not..
        assertFalse("Directory:"+dir.getPath()+" still exist",dir.exists());
        //Now getInstance Method will throw ClassNotFoundException because OkHttpNetworkResponse.Builder.class has been deleted programatically. 
        Factory.getInstance("OkHttpNetworkResponse.Builder.class");
    }

    private void deleteDirectoryProgramatically(String directory) {
        File dir = new File(directory);
        System.out.println(dir.getAbsolutePath());
        String[] files = dir.list();
        for (String f : files) {
            File fl = new File(directory,f);
            System.out.println(f+ " deleted?"+fl.delete());
        }
        System.out.println(dir+ " deleted?"+dir.delete());
    }
}

答案 3 :(得分:2)

这是一个非常简单的问题。下面给出了JUnit4异常单元测试的一个例子。希望它会澄清你。

MyNumber.java

public class MyNumber {
   int number;
   public MyNumber div(MyNumber rhs) {
      if (rhs.number == 0) throw new IllegalArgumentException("Cannot divide by 0!");
      this.number /= rhs.number;
      return this;
   }
}

MyNumberTest.java

public class MyNumberTest {
   private MyNumber number1, number2; // Test fixtures
   @Test(expected = IllegalArgumentException.class)
   public void testDivByZero() {
      System.out.println("Run @Test testDivByZero"); // for illustration
      number2.setNumber(0);
      number1.div(number2);
   }
}

JUnit - 例外测试

要测试代码是否抛出所需的异常,请使用注释@Test(expected = exception.class),如上例所示。对于你的情况,它将是

/**
* Check for class not found exception
**/
@Test(expected=ClassNotFoundException.class)
public void testClassNotFoundException() {
    .....
}
  

为了更好地理解,您可以阅读本教程:Java Unit Testing - JUnit & TestNG。它包含完整运行的代码示例   一步一步解释。

答案 4 :(得分:0)

在catch内部,您可以使用instanceof运算符检查对象:

param

答案 5 :(得分:0)

这是你的字典问题。在测试类的字典中不会有。改变你的字典。

答案 6 :(得分:0)

使用 Class.forName(“com.example.ClassName”)

try {
 Class.forName("com.example.OkHttpNetworkResponse.Builder");
} catch (ClassNotFoundException e) {
  // This class was not found
}

请参阅Class.forName(String className)