我正在尝试测试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 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 }
关于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 { } }
- 我有一个工厂,它将尝试实例化(使用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(); } }
- 开发人员可能会删除一些依赖项,例如删除所有com.example.package
- 我想测试这个案例,但我发现的只是依赖关系的问题,而不是如何测试它。
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的一个例子。 希望它会澄清你。
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; } }
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); } }
要测试代码是否抛出所需的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)