Unit testing 使用另一个类加载器进行JUnit测试

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

我正在写一些Minecraft MOD,我想写单元测试。不幸的是,Minecraft forge并不是为了进行单元测试而建造的

但对此我说:不!我将编写单元测试

因此,Minecraft Forge要求使用net.Minecraft.launchwrapper.LaunchClassLoader。实际上,库中的任何函数调用都会导致断言正在使用此加载程序,并在任何其他情况下引发异常

为了避免这种情况,我已经能够在下面的测试类的设置方法中使用反射

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测试上设置类加载器?是的,但你不会想这么做的。