如何在基于代理的Spring bean中设置模拟对象?

时间:2011-04-06 20:49:57

标签: java unit-testing spring mocking mockito

我在尝试在我的测试用例中的有线bean中设置模拟对象时遇到问题。

这是我的简化问题: -

class SomeClassTest {
    @Autowired
    private SomeClass   someClass;

    @Test
    public void testRun() {
        Service service = mock(ServiceImpl.class);
        when(service.doIt()).thenReturn("");

        // this line fails with ClassCastException
        ((SomeClassImpl) someClass).setService(service);

        assertEquals("bad", someClass.run());
    }
}

interface SomeClass {
    String run();
}

class SomeClassImpl implements SomeClass {
    private Service service;

    public void setService(Service service) {
        this.service = service;
    }

    public String run() {
        String value = service.doIt();
        return StringUtils.isBlank(value) ? "bad" : "good";
    }
}

interface Service {
    String doIt();
}

class ServiceImpl implements Service {
    public String doIt() {
        return "bla";
    }
}

在这个例子中,我试图通过模拟SomeClass来测试Service.doIt(),以便我可以测试不同的条件。我面临的问题是我不确定我应该如何在SomeClass中设置模拟服务对象。我能想到的唯一方法是将SomeClass转发到具体类中以调用setService(...),但是,我得到一个ClassCastException,说 $ Proxy与SomeClassImpl 不兼容。我相信所有的bean接线都是基于代理的,因为我使用AOP来配置事务。我真的不想在setService(...)接口中公开SomeClass,因为在我的生产代码中这样做是没有意义的。

我有办法实现这个目标吗?

感谢。

2 个答案:

答案 0 :(得分:1)

您可以将@Resource注释用于get the implementation

@Resource
private SomeClassImpl someClass;
...
someClass.setService(service);
...

答案 1 :(得分:0)

  1. 使用服务设置器的附加接口。 或
  2. 不要自动装配服务,而是在测试中使用“新”操作符。