gpt4 book ai didi

java - 无法保证 Spring Boot 测试隔离

转载 作者:行者123 更新时间:2023-12-02 01:51:10 26 4
gpt4 key购买 nike

我创建了一个 SpringBoot 测试:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:application-dev.properties")
@Transactional
public class ContactTests2 {
private Logger log = LogManager.getLogger();

@PersistenceContext
private EntityManager entityManager;

@Autowired
private ContactRepository customerRepository;

@Autowired
private StoreRepository storeRepository;

@Autowired
private NoteService noteService;

@Autowired
private Validator validator;

private Store store;

@Before
@WithMockUser(roles = "ADMIN")
public void setup() {
log.debug("Stores {}", storeRepository.count());
store = createStore();
storeRepository.save(store);
}

@Test
@WithMockUser(roles = "ADMIN")
public void saveWithNote() {
Contact customer = new Contact();
customer.setPersonType(PersonType.NATURAL_PERSON);
customer.setFirstName("Daniele");
customer.setLastName("Rossi");
customer.setGender(Gender.MALE);
customer.setBillingCountry(Locale.ITALY.getCountry());
customer.setShippingCountry(Locale.ITALY.getCountry());
customer.setStore(store);

Note note = new Note();
note.setGenre(NoteGenre.GENERIC);
note.setOperationType(AuditType.NOTE);
note.setText("note");

customer = customerRepository.save(customer);

noteService.addNote(note, customer);
}

@Test
@WithMockUser(roles = "ADMIN")
public void save() {
Contact customer = new Contact();
customer.setPersonType(PersonType.NATURAL_PERSON);
customer.setFirstName("Daniele");
customer.setLastName("Rossi");
customer.setGender(Gender.MALE);
customer.setBillingCountry(Locale.ITALY.getCountry());
customer.setShippingCountry(Locale.ITALY.getCountry());
customer.setStore(store);

customerRepository.save(customer);

assertEquals(customer, customerRepository.findById(customer.getId()).get());
}

// ====================================================
//
// UTILITY METHODS
//
// ====================================================

private Store createStore() {
Store store = new Store();
store.setName("Padova");
store.setCode("PD");
store.setCountry("IT");
return store;
}
}

这是笔记服务:

@Service
@Transactional
@PreAuthorize("isAuthenticated()")
public class NoteService {

@PersistenceContext
private EntityManager entityManager;

@Autowired
private NoteRepository noteRepository;

/**
* Add a note to a specific object (parent).
*
* @param note
* @param parent
* @return the added note
*/
public Note addNote(Note note, Persistable<Long> parent) {
// ****************************************************
// VALIDATION CHECKS
// ****************************************************
Assert.notNull(note, InternalException.class, ExceptionCode.INTERNAL_ERROR);
Assert.notNull(parent, InternalException.class, ExceptionCode.INTERNAL_ERROR);
// ****************************************************
// END VALIDATION CHECKS
// ****************************************************

note.setParentId(parent.getId());
note.setParentType(parent.getClass().getSimpleName());
note.setRemoteAddress(NetworkUtils.getRemoteIpFromCurrentContext());

note = noteRepository.save(note);

return note;
}
}

我正在使用 Hibernate 和 Mysql 5.7。问题在于测试调用了 saveWithNote()。当我运行此测试时,以下测试失败,因为 setup() 方法抛出重复的异常。看来之前的测试没有回滚。

这就是发生的事情:

enter image description here

删除行 noteService.addNote(note, customer); 一切都像魅力一样。

我做错了什么?为什么没有保留测试隔离?

最佳答案

这是因为您使用真实的数据存储作为依赖项。运行 saveWithNote() 时,客户条目将保留在数据库中。它不会在您的测试设置中删除,因此当您运行 save() 时,您会遇到重复的数据库条目。

解决方案 1:使用teardown() 方法删除您在测试期间创建的数据库条目。示例:

    @After
@WithMockUser(roles = "ADMIN")
public void teardown() {
// delete the customer entry here
}

引用:https://examples.javacodegeeks.com/core-java/junit/junit-setup-teardown-example/

解决方案 2:每次运行 setup() 时,都将数据库表删除干净。示例:

    @Before
@WithMockUser(roles = "ADMIN")
public void setup() {
// wipe your database tables to make them empty
}

解决方案 1 和 2 都应该仅使用测试数据库来完成。您不想想要清理生产数据库。

解决方案 3(推荐):使用模拟存储库和模拟注入(inject)(而不是通过实际实现 Autowiring 存储库)。

示例/引用:https://stackoverflow.com/a/36004293/5849844

关于java - 无法保证 Spring Boot 测试隔离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52974927/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com