Unit testing 使用另一个类加载器进行JUnit测试
我正在写一些Minecraft MOD,我想写单元测试。不幸的是,Minecraft forge并不是为了进行单元测试而建造的 但对此我说:不!我将编写单元测试 因此,Minecraft Forge要求使用net.Minecraft.launchwrapper.LaunchClassLoader。实际上,库中的任何函数调用都会导致断言正在使用此加载程序,并在任何其他情况下引发异常 为了避免这种情况,我已经能够在下面的测试类的设置方法中使用反射Unit testing 使用另一个类加载器进行JUnit测试,unit-testing,junit,classloader,minecraft,minecraft-forge,Unit Testing,Junit,Classloader,Minecraft,Minecraft Forge,我正在写一些Minecraft MOD,我想写单元测试。不幸的是,Minecraft forge并不是为了进行单元测试而建造的 但对此我说:不!我将编写单元测试 因此,Minecraft Forge要求使用net.Minecraft.launchwrapper.LaunchClassLoader。实际上,库中的任何函数调用都会导致断言正在使用此加载程序,并在任何其他情况下引发异常 为了避免这种情况,我已经能够在下面的测试类的设置方法中使用反射 package net.minecraftforge
package net.minecraftforge.oredict;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.Comparator;
import net.minecraft.block.Block;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.Ordering;
import com.google.common.io.Files;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
import cpw.mods.fml.relauncher.Side;
public class RecipeSorterTest {
public static Ordering<IRecipe> ordering = Ordering.from(new Comparator<IRecipe>() {
@Override
public int compare(IRecipe o1, IRecipe o2) {
return RecipeSorter.INSTANCE.compare(o1, o2);
}
});
private LaunchClassLoader lcl;
@Before
public void setUp() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchFieldException {
Object[] data = new Object[] { "", "", "", "", "1.7.10", "", Files.createTempDir(), Collections.EMPTY_LIST };
URL[] urLs = ((URLClassLoader) Launch.class.getClassLoader()).getURLs();
this.lcl = new LaunchClassLoader(urLs);
Class<?> itemz = lcl.loadClass("cpw.mods.fml.relauncher.FMLRelaunchLog");
Field mz = itemz.getDeclaredField("side");
mz.setAccessible(true);
mz.set(itemz, Enum.valueOf((Class<Enum>) mz.getType(), "CLIENT"));
Class<?> item1 = lcl.loadClass("cpw.mods.fml.common.Loader");
Method m1 = item1.getMethod("injectData", Object[].class);
m1.invoke(null, new Object[] { data });
Class<?> item = lcl.loadClass("net.minecraft.item.Item");
Method m = item.getMethod("registerItems");
m.invoke(null);
// Here's what I'd rather do
// JUnit.setMyClassLoader(new LaunchClassLoader(urLs))
// Loader.injectData(data)
// Item.registerItems();
// Block.registerBlocks();
}
@Test
public void myTest() {
}
}
但这很烦人,很难维持,也很难信任。因此,我想找到一种方法,让我的JUnit测试使用LaunchClassLoader来加载类
我看到了这个答案:
但它似乎并没有解决我的问题。甚至当我尝试使用LaunchClassLoader而不是所描述的TestClassLoader时,我也无法运行任何单元测试,因为每次尝试时都会出现一个no-runnable-methods错误
有没有一种简单的方法可以在JUnit测试上设置类加载器?
不,我不能更改代码库,这必须从单元测试中完成有没有一种简单的方法可以在JUnit测试中设置类加载器?没有。有没有办法在JUnit测试上设置类加载器?是的,但你不会想这么做的。