我在下面的测试中模拟了AuthService,并将authService.checkAuthority(any(UserAuthority.class))设置为“true”。它实际上已经设置但在实际方法(authService.checkAuthority(UserAuthority.COMMENT_ACCESS))中它将值变为false。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(ApplicationRunner.class)
@WebAppConfiguration
@Transactional
public class TagsTest extends BaseWebTest {
@Autowired
private TagService tagService;
@Autowired
private TagRepository repository;
UserDetailsDto currentUser;
@Autowired
protected AuthService authService;
@Autowired
protected StringRedisTemplate stringRedisTemplate;
@Autowired
protected FilterChainProxy filterChainProxy;
@Autowired
protected WebApplicationContext context;
protected static MockMvc mvc;
@Before
@Override
public void setUp() {
MockitoAnnotations.initMocks(this);
mvc = MockMvcBuilders.webAppContextSetup(context)
.dispatchOptions(true)
.addFilters(filterChainProxy)
.build();
authService = Mockito.mock(AuthService.class);
Mockito.reset(authService);
when(authService.getCurrentUser()).then(i->(getCurrentUser()));
when(authService.checkAuthority(any(UserAuthority.class))).
thenReturn(true);
login(WORKFLOW_USER);
}
感谢任何帮助。提前谢谢!
答案 0 :(得分:1)
只需删除此作业即可解决您的具体问题:
authService = Mockito.mock(AuthService.class);
您的目标是使用SpringJUnit4ClassRunner
在图表中创建一些依赖项,并使用Mockito来模拟其他依赖项。但是,与this SO answer中一样,测试中标有@Autowired
的任何内容都是在@Before
方法运行之前创建的。这意味着您上面替换authService
的调用只会覆盖测试中的字段;它不会调整或更改已创建的任何其他@Autowired
字段,以及已使用您在Spring配置中绑定的authService
的字段。
如果这是一个单元测试,并且您只是测试TagsService
和TagsRepository
,则可能需要通过使用@Mock和@Autowired字段的组合调用其构造函数来手动创建这些对象:
TagRepository repository = new TagRepository(/*mock*/ authService);
TagService tagService = new TagService(/*mock*/ authService, /*real*/ repository);
(Mockito提供了一种使用@InjectMocks自动创建模拟的方法,但是因为如果无法检测到适当的模拟,它会无声地失败,您可能希望避免这种情况并改为调用构造函数。{{ 3}})
请注意,上述内容仅适用于您在单元测试中直接使用对象,而不是当您依靠Spring的自动装配将对象更深入地插入图形时。
您发布的测试看起来像是网络或集成测试,因此您希望在创建期间用模拟替换authService
的实例。通常,这意味着要更改配置XML或ApplicationRunner,以指示Spring使用Mockito模拟而不是真正的AuthService。虽然有很多方法可以做到这一点,但您可能希望使用以Mockito为中心的FactoryBean
See this article for some good reasons and solutions.。
但等等!您可能正在使用已为Mockito定制的ApplicationRunner。由于三个原因,authService = Mockito.mock(AuthService.class);
行看起来非常不合适:
@Autowired
字段Mockito.mock
,但仍然是手动调用MockitoAnnotations.initMocks(this)
,这通常是首选reset
您创建的模拟这表明我的@Autowired
authService
已经已经成为模拟者,并且已经已经有了存根,这就是为什么你有剩下的reset
。如果是这样,那么你的问题不是关于Mockito的问题,除了你(或某人)已经覆盖字段并存根本地副本而不是Spring在整个网络测试中安装的副本。这可以很容易地解决:删除你的现场重新分配,你可能会很高兴。