Spring - 单元测试中的Skip init-method

时间:2009-07-02 17:10:15

标签: java spring

我想在Junit测试用例中测试Spring配置,而无需在配置的bean上调用init-method。我可以编写我的init方法来跳过基于系统属性的实际工作,这可能是在测试用例中设置的,但我正在寻找一个更清晰的解决方案。

5 个答案:

答案 0 :(得分:3)

您的JUnit测试是否使用相同的Spring上下文配置文件?我猜测答案是肯定的......如果您的测试使用备用弹簧配置,它将简化问题。

我使用过的一种最干净的方法是使用一些方便的注释,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class MovieServiceTest {
    // ...
}

Spring将其称为“TestContext框架”,JUnit测试将查找上下文配置文件,对于上面的示例,名称为“MovieServiceTest-context.xml”

然后,您可以在不使用init方法的情况下定义bean。虽然......你也不想测试它吗?

答案 1 :(得分:1)

这是一个在Spring的配置XML中由bean的init-method属性指定的init方法吗?如果是这样,你不能使用不同的上下文XML来运行你在生产中使用的测试来实现这个目标吗?

答案 2 :(得分:0)

你可以去一点老派并扩展正在测试的类并覆盖init方法。

或者你可以重构一下并注入init方法使用的init策略对象。

我更喜欢testContext.xml方式......

答案 3 :(得分:0)

决定回答我自己的问题,分享找到的解决方案。不喜欢使用init-methods维护配置文件的另一个副本的解决方案。我的解决方案并不完美,但可以完成工作。

public final static String INIT_METHOD_REGEX = "init-method=\"\\w+\"";
public final static String DESTROY_METHOD_REGEX = "destroy-method=\"\\w+\"";
public final static String PROPERTY_REGEX = "\\$\\{[^\\}]+\\}";

private static List<List<String>> subs = new ArrayList<List<String>>();
static {
    subs.add(Arrays.asList( new String[] { INIT_METHOD_REGEX, "" }));
    subs.add(Arrays.asList( new String[] { DESTROY_METHOD_REGEX, "" }));
    subs.add(Arrays.asList( new String[] { PROPERTY_REGEX, "" }));
}

static public void testSpringConfig(String configFile) throws IOException {
    URL springXml = Thread.currentThread().getContextClassLoader().getResource(configFile);
    InputStream is = springXml.openStream();
    byte[] buffer = new byte[8192];
    int readBytes;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    while ((readBytes = is.read(buffer)) != -1)
        baos.write(buffer, 0, readBytes);

    String content = baos.toString();
    for (List<String> s : subs) 
        content = content.replaceAll(s.get(0), s.get(1));

    ByteArrayInputStream bais = new ByteArrayInputStream(content.getBytes());
    InputSource isrc = new InputSource(bais);

    GenericApplicationContext ctx = new GenericApplicationContext();
    XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
    xmlReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
    xmlReader.loadBeanDefinitions(isrc);

    ctx.refresh();
    ctx.start();
    ctx.close();
}

答案 4 :(得分:0)

这是单元测试还是集成测试?如果是单元测试,那么您不应该加载上下文,因此您不必担心init方法。如果是集成测试,我指的是任何验证几个类之间交互的测试,那么你需要确保调用init方法以确保有效的测试。

尽管如此,上一篇文章在头部发现,使用了一个不调用init方法的不同上下文。