Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Unit test JPA repository

I'm new to Spring framework. I need to write Unit Test for JPA repository. I'm trying simple repository saveAndFlush() method. But nothing saves in my repository. Here is my source code:

TestContext.class

@Configuration 
@PropertySource("classpath:log4j.properties") 
public class TestContext {

    @Bean
    public RoleService roleService() {
        return Mockito.mock(RoleService.class);
    }

    @Bean
    public RightService RightService() {
        return Mockito.mock(RightService.class);
    }

    @Bean
    public RoleRepository RoleRepository() {
        return Mockito.mock(RoleRepository.class); 
    }
}

RoleServiceTest.class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestContext.class})
@WebAppConfiguration
public class RoleServiceTest {

    @Autowired
    private RoleRepository roleRepository;

    @Test
    public void TestServices() throws Exception {
        RoleDetails first = new RoleDetails();
        first.setId("1");
        first.setDescription("First Description");
        first.setName("First");
        roleRepository.saveAndFlush(new RoleEntity(first));
        roleRepository.save(new RoleEntity(first));
        List<RoleEntity> roles = new ArrayList<RoleEntity>();
        roles = roleRepository.findAll();
        System.out.println(roles);
        assertEquals(1, roles.size());
    }
}

And error:

java.lang.AssertionError: expected:<1> but was:<0>

I'm almost sure that problem occurs because of testContext.Class. I used this class to test my controller and it worked well, but now i need to test my database and i don't know how to modify contextConfiguration. I hope somone will help me. Thanks in advance!

like image 310
Egizeris Avatar asked Jun 23 '14 14:06

Egizeris


3 Answers

The problem is from the TestContext indeed. You try to save your object using a mock object, which is not correct.

The solution is to use the real repository. For this, you need to follow the next steps:

  1. Annotate your RoleRepository with the @Repository annotation and extend the class with JpaRepository(RoleEntity,ID) (where ID is the type you declared the id of the RoleEntity).
  2. Add the RoleRepository to your Context Configuration class (the real one, not a test one). You can do this by adding @EnableJpaRepositories(value="your.repository.package").
  3. Replace the TestContext.class from your @ContextConfiguration annotation on your RoleServiceTest class with your real Context Configuration class you used to configure your Spring based project.

I hope my answer helps, if you still need help feel free to ask again!

like image 66
radusezciuc Avatar answered Nov 15 '22 21:11

radusezciuc


If using Spring Boot, creating a web app and you're running off of a main() method within an Application.class you could use:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class MyUnitTest {

    Some someInstance = new Some();

    @Autowired
    private SomeRepository someRepository;
}

@Test
public void testSomeClass() throws Exception {
    Some savedSome = someRepository.save(someInstance);
    assertEquals(1, someRepository.count());
}
like image 37
Baker Avatar answered Nov 15 '22 22:11

Baker


Your repository is a mock object. A mock object, by definition, is an object that doesn't do what it should normally do, but does what you tell it to do in the test.

To test the repository, the repository must be a real one. Your context class should thus rather have

@Bean
public RoleRepository RoleRepository() {
    return new RoleRepositoryImpl(); // or whatever the class implementing the repository is 
}
like image 28
JB Nizet Avatar answered Nov 15 '22 21:11

JB Nizet