【问题标题】:Spring not calling @Bean method in testsSpring没有在测试中调用@Bean方法
【发布时间】:2018-10-08 12:13:14
【问题描述】:

我有一个存储库MyRepository,它是一个@Repository。这个存储库由我的一个休息控制器使用。我要测试的是我的休息控制器的授权是否正常工作,因此我的测试使用@WithUserDetails。我想通过关注this tutorial 来模拟对MyRepository 的调用。当我运行我的测试时,我得到一个异常说:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

通过一些调试,我发现我的MockConfig#myRepository 方法没有被调用。

src/main/java/com.example

我的仓库

@Repository
interface MyRepository extends CrudRepository<MyEntity, Long> {}

src/test/java/com.example

模拟配置

@Profile("test")
@Configuration
public class MockConfig
{
    @Bean
    @Primary
    public MyRepository myRepository()
    {
        return Mockito.mock(MyRepository.class);
    }
}

我的测试类

@ActiveProfiles("test")
@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class)
@TestExecutionListeners({
    DependencyInjectionTestExecutionListener.class
})
class MyTestClass
{
    @Autowired
    private MockMvc mvc;

    @Autowired
    private MyRepository myRepository;

    @Test
    @WithUserDetails("some_user")
    public void testWithCorrectPermissions()
    {
        long entityId = 1;

        MyEntity mockReturnValue = new MyEntity();
        Mockito.when(myRepository.findOne(entityId)).thenReturn(mockReturnValue);
        Mockito.when(myRepository.save(mockReturnValue)).thenReturn(mockReturnValue);

        this.mockMvc.perform(post("my/api/path")).andExpect(status().isOk());
    }
}

【问题讨论】:

    标签: java spring junit mockito


    【解决方案1】:

    尝试How to exclude a @Repository from component scan when using Spring Data Rest中提出的解决方案

    将以下注释添加到您的测试类

    @EnableJpaRepositories(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {MyRepository.class})})
    class MyTestClass
    (...)
    

    【讨论】:

    • 我不太明白为什么我必须从组件扫描中排除MyRepository。你能给我一些背景信息吗?
    【解决方案2】:

    如果你想为你的测试类模拟依赖项(例如存储库),我建议你使用 MockitoJUnitRunner.class 因为 SpringRunner.class 将初始化 Spring 应用程序内容,这将导致测试更慢而且更多所需的依赖项取决于您的项目配置。

    所以,对于你的 MyTestClass

    @RunWith(MockitoJUnitRunner.class)
    public class MyTestClass{
        @Mock
        private MyRepository myRepository;
    
        private MyTest myTest;
    
        @Before
        public void setUp() throws Exception {
           myTest = new MyTest(myRepository);
        }
    
        @Test
        public void test(){
            ...
            when(myRepository.get(anyInt()).thenReturn(new MyEntity());
            ...
        }
    

    有一些参考here

    如果您坚持使用当前实现进行测试,则可能是 MyRepository 被 Spring Data 扫描并且 bean 被它初始化。您可能希望按照 user2456718 的建议禁用组件扫描。

    【讨论】:

    • 使用 MockitoJUnitRunner 对我不起作用,因为我需要登录我的 Spring 应用程序,因此我的测试使用 @WithUserDetails。我的测试的目的是在我的休息端点上测试授权。我想我应该把这个包含在我的问题中
    猜你喜欢
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    相关资源
    最近更新 更多