【问题标题】:Mock repository used by JPQL query while testingJPQL 查询在测试时使用的模拟存储库
【发布时间】:2016-08-31 07:40:30
【问题描述】:

我想用相关的 JPQL 测试 CRUD 存储库:

@Repository
public interface UserRolesRepository extends CrudRepository<UserRoles, Long> {

@Query("SELECT a.role FROM UserRoles a, UserEntity b WHERE b.username=?1 AND a.id=b.id")
public List<String> findRoleByUserName(String name);
}

我的问题是模拟与 UserEntity 相关的存储库。我试图模拟用户存储库的方法,但它们似乎从未被调用过。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BlogCmsApplication.class)
public class UserRolesRepositoryTest {
@Autowired
UserRolesRepository userRolesRepository;
@Mock
UserRepository userRepository;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);

}

@Test
public void findRoleByUserName() throws Exception {
    UserEntity user = new UserEntity("user467","somepass");
    user.setId(1);
    Mockito.when(userRepository.findByUsername(user.getUsername())).thenReturn(user);
    Mockito.when(userRepository.findOne(user.getId())).thenReturn(user);
    Mockito.when(userRepository.exists(user.getId())).thenReturn(true);


    UserRoles role = new UserRoles(1,"ROLE_USER");
    userRolesRepository.save(role);

    List<String> actualRole;
    actualRole = userRolesRepository.findRoleByUserName(user.getUsername());

    List<String> expectedRole = new ArrayList<>();
    expectedRole.add(role.getRole());

    assertNotNull(actualRole);
    assertEquals(expectedRole,actualRole);

}

@Autowired 可以正常工作,但这不是重点。 断言错误是

Expected :[ROLE_USER]
Actual   :[]

【问题讨论】:

    标签: java spring unit-testing junit mockito


    【解决方案1】:

    是的,你可以在这里使用@MockBean,Spring Boot 包含一个@MockBean 注解,可以用来为一个bean 定义一个Mockito mock 在您的 ApplicationContext 中。您可以使用注解添加新的 bean,或替换单个 现有的 bean 定义。注释可以直接用于测试类,测试中的字段, 或@Configuration 类和字段。在字段上使用时,创建的模拟实例将 也被注入。模拟 bean 在每个测试方法之后都会自动重置。

    @RunWith(SpringRunner.class)
    @DataJpaTest
    @Transactional
    public class SpringBootJPATest {
    
        @MockBean
        private BlogEntryRepository blogEntryRepository;
    
        @Autowired
        private TestEntityManager entityManager;
    
        @Test
        public void jpa_test() {
            BlogEntry entity = new BlogEntry();
            entity.setTitle("Test Spring Boot JPA Test");
            BlogEntry persist = entityManager.persist(entity);
            System.out.println(persist.getId());
        }
    
        @Test
        public void jap_test_repo() {
            BlogEntry entity = new BlogEntry();
            entity.setTitle("Test Spring Boot JPA Test");
            BlogEntry persist = blogEntryRepository.save(entity);
            // System.out.println(persist.getId()); // This line will get a NPE as the repo is using the mocked bean
        }
    }
    

    【讨论】:

    • 不幸的是,对我不起作用:/ 引发初始化错误:java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy 我一直在尝试使用@InjectMock,但没有成功。此查询无法正常工作:userRolesRepository.findRoleByUserName(user.getUsername())
    • @zfChaos 我这里用的是sprint boot 1.4,你用的是哪个版本?
    • 1.3.5 但我已更改为 1.4 以测试此解决方案。控制台输出:Hibernate: insert into user_roles (id, role, user_id) values (null, ?, ?),所以这会给真实数据库带来麻烦。
    • @zfChaos 您需要为您的实体添加ID生成,例如,添加@Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id;作为主键。
    • 我确实知道了。它适用于@Autowired@DataJpaTest 导致上述错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    相关资源
    最近更新 更多