在Spring单元测试中,如果需要获取代理类的真正对象,可以使用以下方法:
- 使用Mockito框架
import static org.mockito.Mockito.mockingDetails;
@Service
public class MyServiceImpl implements MyService {
@Override
public void doSomething() {
MyService myService = (MyService) mockingDetails(this).getMock();
// do something with myService
}
}
// Unit test
@RunWith(MockitoJUnitRunner.class)
public class MyServiceImplTest {
@InjectMocks
private MyServiceImpl myService;
@Test
public void testDoSomething() {
myService.doSomething(); // the real MyServiceImpl instance is used
}
}
- 使用@Spy注解
@Service
public class MyServiceImpl implements MyService {
@Autowired
private MyService self;
@Override
public void doSomething() {
MyService myService = (MyService) ((Advised) self).getTargetSource().getTarget();
// do something with myService
}
}
// Unit test
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceImplTest {
@SpyBean // or @MockBean
private MyServiceImpl myService;
@Test
public void testDoSomething() {
myService.doSomething(); // the real MyServiceImpl instance is used
}
}
注:使用@Spy或@Mock注解时,需要将实现类替换为代理类。在上述例子中,MyServiceImpl已经被声明成了@Service,因此不能直接使用@Spy或@Mock注解。可以通过另外声明一个包可见的内部类来做到这一点,如下所示:
@Service
public class MyServiceImpl implements MyService {
@Autowired
private MyService self;
@Override
public void doSomething() {
MyService myService = (MyService) ((Advised) self).getTargetSource().getTarget();
// do something with myService
}
static class Spy extends MyServiceImpl {}
}
// Unit test
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceImplTest {
@SpyBean
private MyServiceImpl.Spy myService;
@Test
public void testDoSomething() {
myService.doSomething(); // the real MyServiceImpl instance is used
}
}