9

@Aspectすべてのコントローラー アクション メソッドの実行を織り込む があります。システムを実行すると問題なく動作しますが、単体テストでは動作しません。私は次のようにMockitoとjunitを使用しています:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:**/spring-context.xml")
@WebAppConfiguration
public class UserControllerTest {        
    private MockMvc mockMvc;

    @Mock
    private RoleService roleService;

    @InjectMocks
    private UserController userController;

    @Before
    public void setUp() {
       MockitoAnnotations.initMocks(this);                    
       ...    
       mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }    
    ...
}

一部@Test使用してmockMvc.perform()います。

そして、私の側面は次のとおりです。

@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controller() { }

@Pointcut("execution(* mypackage.controller.*Controller.*(..))")
public void methodPointcut() { }

@Around("controller() && methodPointcut()")
...
4

2 に答える 2

10

最初に、Jason が提案したように webAppContextSetup を使用する必要があります。

@Autowired
private WebApplicationContext webApplicationContext;

@Before
public void setUp() throws Exception {
   ...
   mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}

この時点で、アスペクトはトリガーされますが、Mockito はモックを挿入しません。これは、Spring AOP がプロキシ オブジェクトを使用し、モックがプロキシ オブジェクトではなくこのプロキシ オブジェクトに注入されているためです。これを修正するには、オブジェクトをアンラップし、@InjectMocks アノテーションの代わりに ReflectionUtils を使用する必要があります。

private MockMvc mockMvc;

@Mock
private RoleService roleService;

private UserController userController;

@Autowired
private WebApplicationContext webApplicationContext;

@Before
public void setUp() {
   MockitoAnnotations.initMocks(this);                    
   UserController unwrappedController = (UserController) unwrapProxy(userController);
   ReflectionTestUtils.setField(unwrappedController, "roleService", roleService);   
   mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}

...

public static final Object unwrapProxy(Object bean) throws Exception {
/*
 * If the given object is a proxy, set the return value as the object
 * being proxied, otherwise return the given object.
 */
    if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
        Advised advised = (Advised) bean;
        bean = advised.getTargetSource().getTarget();
    }
    return bean;
}

この時点で、 when(...).thenReturn(...) への呼び出しは正しく機能するはずです。

ここで説明されています:http://kim.saabye-pedersen.org/2012/12/mockito-and-spring-proxies.html

于 2014-04-12T22:07:30.537 に答える
0

You are probably using Spring AOP, in which case the bean has to be a Spring bean for AOP to work, by not autowiring in the controller it is bypassing the Spring AOP mechanism totally.

I think the fix should be to simply inject in the controller

 @Autowired
 @InjectMocks
 private UserController userController;
于 2013-06-03T18:11:46.430 に答える