测试ClassNotFoundexception

我正在尝试测试Android上的UnitTest找不到类。

这是怎么回事:
1.我正在编写一个具有transitive依赖关系的android库,这些依赖关系在宿主应用程序中得到解决
2.开发人员可能会删除一些依赖项,例如删除所有com.example.package
3.我有一个工厂,它将尝试实例化(使用reflection)一个Object并捕获ClassNotFoundException 。 如果开发人员删除了依赖项,则应抛出exception。
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。

你知道怎么做吗?

所以对我来说,你需要做的第一件事是提取可以抛出ClassNotFoundException的代码部分,以便能够轻松地模拟它,例如:

 public Class 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 } 

关于Mockito.spy的更多细节。

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

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

OkHttpNetworkResponse.Builder可能如下:

 package com.example.model; public class OkHttpNetworkResponse { public static class Builder { } } 
  1. 我有一个工厂,它将尝试实例化(使用reflection)一个Object并捕获ClassNotFoundException。 如果开发人员删除了依赖项,则应抛出exception。

工厂类:将创建任何对象可能如下:

 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. 我想测试这个案例,但我发现的只是依赖关系的问题,而不是如何测试它。

FactoryTest类:将测试是否抛出ClassNotFoundException可能如下:注意:请仔细检查注释。

 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()); } } 

这是一个非常简单的问题。 下面给出了JUnit4exceptionunit testing的一个例子。 希望它会澄清你。

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 – exception测试

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

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

为了更好地理解,您可以阅读本教程: Javaunit testing – JUnit和TestNG 。 它包含完整运行代码示例,一步一步解释。

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

 try { sNetworkResponseBuilderClass = OkHttpNetworkResponse.Builder.class; } catch (Exception e){ if(e instanceof ClassNotFoundException){ // here you can do the code you want in case of ClassNotFoundException thrown } } 

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

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

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

请参见Class.forName(String className)