测试 ClassNotFound 异常
Testing ClassNotFound Exception
我正在尝试使用 Android 上的 UnitTest 测试未找到 class。
发生了什么:
1. 我正在编写一个 android 库,其中包含 transitive
依赖项,这些依赖项在主机应用程序中解析
2. 开发者可以删除一些依赖,例如 remove all com.example.package
3. 我有一个工厂,它将尝试实例化(使用反射)一个对象并捕获 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。
你知道怎么做吗?
不太确定我是否正确理解了你的问题,但你可以检查 JUnit 是否抛出异常:
@Test(expected=ClassNotFoundException.class)
public void testClassNotFoundException() {
// a case where the exception gets thrown
}
在 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
}
}
这是你的字典问题。在你的字典中 test class 不会有 .换字典。
所以对我来说,您需要做的第一件事是提取可以抛出 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 的更多详细信息。
很简单的问题。下面以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() {
.....
}
For better understanding, you can go through this tutorial: Java Unit
Testing - JUnit & TestNG. It contains full running code example
step by step with explanation.
使用Class.forName("com.example.ClassName")
try {
Class.forName("com.example.OkHttpNetworkResponse.Builder");
} catch (ClassNotFoundException e) {
// This class was not found
}
OkHttpNetworkResponse.Builder可能如下:
package com.example.model;
public class OkHttpNetworkResponse {
public static class Builder {
}
}
- I have a Factory that will try to instantiate (using reflection) an Object and catch the ClassNotFoundException. If the developer remove
the dependencies, the exception should be thrown.
Factory Class: 将创建任何对象可能如下所示:
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();
}
}
- The developer may remove some dependencies for example remove all com.example.package
- I want to test this case, but all I found is issue with dependencies, not how to test for it.
FactoryTest Class: 将测试是否抛出 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());
}
}
我正在尝试使用 Android 上的 UnitTest 测试未找到 class。
发生了什么:
1. 我正在编写一个 android 库,其中包含 transitive
依赖项,这些依赖项在主机应用程序中解析
2. 开发者可以删除一些依赖,例如 remove all com.example.package
3. 我有一个工厂,它将尝试实例化(使用反射)一个对象并捕获 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。
你知道怎么做吗?
不太确定我是否正确理解了你的问题,但你可以检查 JUnit 是否抛出异常:
@Test(expected=ClassNotFoundException.class)
public void testClassNotFoundException() {
// a case where the exception gets thrown
}
在 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
}
}
这是你的字典问题。在你的字典中 test class 不会有 .换字典。
所以对我来说,您需要做的第一件事是提取可以抛出 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 的更多详细信息。
很简单的问题。下面以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() {
.....
}
For better understanding, you can go through this tutorial: Java Unit Testing - JUnit & TestNG. It contains full running code example step by step with explanation.
使用Class.forName("com.example.ClassName")
try {
Class.forName("com.example.OkHttpNetworkResponse.Builder");
} catch (ClassNotFoundException e) {
// This class was not found
}
OkHttpNetworkResponse.Builder可能如下:
package com.example.model;
public class OkHttpNetworkResponse {
public static class Builder {
}
}
- I have a Factory that will try to instantiate (using reflection) an Object and catch the ClassNotFoundException. If the developer remove the dependencies, the exception should be thrown.
Factory Class: 将创建任何对象可能如下所示:
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();
}
}
- The developer may remove some dependencies for example remove all com.example.package
- I want to test this case, but all I found is issue with dependencies, not how to test for it.
FactoryTest Class: 将测试是否抛出 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());
}
}