2017-04-27 99 views
3

我试图使用Spring Boot Test进行简单的集成测试,以测试e2e用例。我的测试不起作用,因为我'不能使资源库保存的数据,我想我和春天有个上下文的问题...春季开机测试@Transactional未保存

这是我的实体:

@Entity 
@Getter 
@Setter 
@NoArgsConstructor 
@AllArgsConstructor 
public class Person { 
    @Id 
    private int id; 
    private String name; 
} 

这是人库:

@Repository 
public interface PersonRepository extends JpaRepository<Person, Integer> { 
} 

的人服务:

@Service 
public class PersonService { 

    @Autowired 
    private PersonRepository repository; 

    public Person createPerson(int id,String name) { 
     return repository.save(new Person(id, name)); 
    } 

    public List<Person> getPersons() { 
     return repository.findAll(); 
    } 
} 

的人控制器:

@RequestMapping 
@RestController 
public class PersonController { 

    @Autowired 
    private PersonService personService; 

    @RequestMapping("/persons") 
    public List<Person> getPersons() { 
     return personService.getPersons(); 
    } 

}

主应用程序类:

@SpringBootApplication 
public class BootIntegrationTestApplication { 

    public static void main(String[] args) { 
    SpringApplication.run(BootIntegrationTestApplication.class, args); 
    } 
} 

的application.properties文件:

spring.datasource.url= jdbc:mysql://localhost:3306/test 
spring.datasource.username=root 
spring.datasource.password=password 
spring.jpa.hibernate.ddl-auto=create 
spring.jpa.show-sql=true 

和测试:

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
public class BootIntegrationTestApplicationTests { 

    @Autowired 
    private PersonService personService; 
    @Autowired 
    private TestRestTemplate restTemplate; 

    @Test 
    @Transactional 
    public void contextLoads() { 
     Person person = personService.createPerson(1, "person1"); 
     Assert.assertNotNull(person); 

     ResponseEntity<Person[]> persons = restTemplate.getForEntity("/persons", Person[].class); 
    } 
} 

测试不起作用,因为服务不保存Person实体.... 预先感谢

+3

那当然不是......你的测试是事务性的,所以事务包装你的测试方法。所以之后会回滚(并且您的服务参与了该交易)。即使你使用'flush'也不行,因为你正在使用rest来访问会打开一个新事务的应用程序。使这项工作的唯一方法是使测试不是事务性的。 –

+0

你可以尝试拆分你的测试。创建私有方法来保存具有事务注释的人并从测试方法中调用它。 – kimy82

+0

正如@ M.Deinum所说,事务在您的测试中回滚,并且您看不到任何更改。尝试在测试中添加'@Commit'或@Rollback(false)。 – dev4Fun

回答

1

感谢M. Deinum,我想我明白了, 所以最好是分开测试的逻辑成两个试验中,先将测试只是该服务(所以这一个可以是事务性)和所述第二控制器:

测试1:

@Test 
@Transactional 
public void testServiceSaveAndRead() { 
    personService.createPerson(1, "person1"); 
    Assert.assertTrue(personService.getPersons().size() == 1); 
} 

试验2:

@MockBean 
private PersonService personService; 

@Before 
public void setUp() { 
    //mock the service 
    given(personService.getPersons()) 
      .willReturn(Collections.singletonList(new Person(1, "p1"))); 
} 

@Test 
public void testController() { 
    ResponseEntity<Person[]> persons = restTemplate.getForEntity("/persons", Person[].class); 
    Assert.assertTrue(persons.getBody()!=null && persons.getBody().length == 1); 
} 

希望它能够帮助别人一天......感谢大家

0
@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Application.class) 

public class SmokeTest { 

    @Rollback(false) //This is key to avoid rollback. 
    @Test 
    public void contexLoads() throws Exception { 
     System.out.println("Hiren"); 

     System.out.println("started"); 
     _userDAO.save(new User("tyx", "[email protected]")); 
    } 

    @Autowired 
    UserController userController; 

    @Autowired 
    UserDao _userDAO; 
} 

参考@Rollback(假)是关键,以避免回滚。