0

我有这么控制器

@Controller
public class MyController {
 @Autowire
 MyClass myClass;
 //myClass doesn't have setter and getter
 .... 
 @RequestMapping("/path")
 public String underTest(){
    myClass.makeSomething();
    return "html.jsp"
}

我想使用 Mockito 和模拟 myClass 进行模拟测试。在测试类中,我想得到 myClass :

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/BeanConfig.xml"); 
myClass = context.getBean("myClass ", MyClass .class);

但是我需要将此 bean 自动连接到 Controller 以测试控制器的方法(我认为测试代码不应该影响正常代码)。

有没有办法在不编写 set 方法的情况下实现它?

我想检查 myClass.makeSomething() 在方法 underTest 中是否调用过一次。

4

4 回答 4

1

只要您的测试与自身MyController位于同一个包中MyController(通常是这样做的 - 不同源文件夹中的相同包),您就可以简单地分配它:

MyController controller = new MyController();
controller.myClass = mockMyClass;

这就是不把@Inject/@Autowired放在private字段上的原因。

于 2013-09-05T12:21:56.943 回答
0

尝试使用 context.getBean() 直接测试控制器。MyClass 将自动装配到其中。

于 2013-09-05T12:05:04.570 回答
0

我同意@axtavt 的回答,但是如果您绝对想按照自己的方式在集成测试中注入模拟,您可以这样做:

定义一个覆盖 bean 配置文件,比如 bean-test-config.xml,其内容如下:

<import resource="classpath:spring/BeanConfig.xml"/>
<bean name="myClass" factory-method="mock" class="org.mockito.Mockito">
 <constructor-arg value="MyClass"></constructor-arg>
</bean>

这应该正确地注入控制器中的模拟。你必须在你的测试中掌握这个模拟,并注入你期望从这个模拟中得到的任何行为。

于 2013-09-05T23:35:38.287 回答
0

我不确定我是否同意您的看法,即测试代码不应影响正常代码。我认为重构/重写生产代码的一个完全正当的理由是使其更具可测试性(这可能是通过使其更加模块化来实现的,这通常是一件好事)。

这正是为什么注释喜欢

@VisibleForTesting

存在。然后,您可以为 MyClass 创建一个包本地设置器,添加上述注释(为其他程序员和可能的代码检查工具提供信息)并在您的测试中设置字段(应位于同一包中)。

或者,由于您使用的是 Mockito,您可以简单地使用 @InjectMocks 注释 MyController 实例,例如

@Test
public class MyControllerTest {

    @Mock
    private MyClass mockMyClass;
    @InjectMocks
    private MyController myController;

    @BeforeMethod
    public void before() {
        MockitoAnnotations.initMocks(this);
    }

    // do tests...
}

请注意,@InjectMocks 不依赖于目标字段上的任何注释(即@Autowired、@Resource、@Inject 等)。它只是工作。(大概你仍然需要那些注解来进行 Spring 注入,所以不要删除它们!关键是你也可以将它用于未注解的字段)。

另请注意,根据您使用的 Mockito 版本,您可能需要在调用 MockitoAnnotations.initMocks() 之前在 before() 方法中实例化 MyController

于 2013-09-05T12:11:40.040 回答