Junit 测试由于共享实例而失败(我认为)
Junit tests fail due shared instances (i think)
我认为我的问题与此问题有关:
Tests pass when run individually but not when the whole test class run
我的测试都单独通过了,但是当我 运行 测试 class 时,其中两个失败了。调试显示 assertEquals 期望的状态与代码中给出的状态不同,主要是来自不同测试的状态。解决方案应该使用 @Before 或 @After 并进行清理,但我在使用它时遇到了麻烦,因为该实例是从 Spring.
自动装配的
主要问题:我的想法是否正确,我如何'reset'自动装配实例?
@SpringBootTest
class StatementProcessorServiceTest {
@Autowired
StatementProcessorService statementProcessorService;
private StatementProcessorInputModel setup(long id, boolean endbalanceCorrect) {
StatementProcessorInputModel statementProcessorInputModel = new StatementProcessorInputModel();
statementProcessorInputModel.startBalance = 1.00;
statementProcessorInputModel.id= id;
statementProcessorInputModel.startBalance = 1.00;
statementProcessorInputModel.mutation = 1.00;
statementProcessorInputModel.endBalance = endbalanceCorrect ? 2.00 : 1.00;
return statementProcessorInputModel;
}
@Test
void verify_with_all_good_settings()
{
StatementProcessorResponseModel sut;
sut = statementProcessorService.validate(setup(1, true));
Assert.assertEquals(sut.result, "SUCCESSFUL");
}
@Test
void verify_with_good_settings_but_duplicated_reference()
{
StatementProcessorResponseModel sutFirst = statementProcessorService.validate(setup(2, true));
Assert.assertEquals(sutFirst.result, "SUCCESSFUL");
StatementProcessorResponseModel sutSecond;
sutSecond = statementProcessorService.validate(setup(2, true));
Assert.assertEquals(sutSecond.result, "DUPLICATE_REFERENCE");
}
@Test
void verify_with_wrong_endBalance_and_good_reference()
{
StatementProcessorResponseModel sut = statementProcessorService.validate(setup(3, false));
Assert.assertEquals(sut.result, "INCORRECT_END_BALANCE");
}
@Test
void verify_with_all_wrong_settings()
{
StatementProcessorResponseModel sutFirst = statementProcessorService.validate(setup(4, true));
Assert.assertEquals(sutFirst.result, "SUCCESSFUL");
StatementProcessorResponseModel sutSecond = statementProcessorService.validate(setup(4, false));
Assert.assertEquals(sutSecond.result, "DUPLICATE_REFERENCE_INCORRECT_END_BALANCE");
}
}
编辑 1:添加了服务代码
@Component
public class StatementProcessorService {
private StatementProcessorResponseModel responseModel = new StatementProcessorResponseModel();
private static ArrayList<Long> usedReferences = new ArrayList<>();
public StatementProcessorResponseModel validate(StatementProcessorInputModel inputModel){
if(!validateUniqueReference(inputModel.transactionReference))
{
responseModel.errorRecords.add("account_number_of_ inCorrectEndBalance _record");
responseModel.result = "DUPLICATE_REFERENCE";
}
if(!validateMutation(inputModel))
{
responseModel.errorRecords.add("account_number_of_ inCorrectEndBalance _record");
if (!responseModel.result.isBlank()){
responseModel.result = responseModel.result + "_INCORRECT_END_BALANCE";
}
else{
responseModel.result = "INCORRECT_END_BALANCE";
}
}
if (responseModel.result.isBlank()){
responseModel.result = "SUCCESSFUL";
}
return responseModel;
}
如果你标记你的测试 cases/classes 修改数据库 @Transactional
然后测试运行器将在测试后回滚事务。
您似乎没有使用数据库来存储状态,因此在不知道如何存储此状态的情况下很难添加完整的答案。不管 StatementProcessorService
必须以某种方式存储状态,所以我将尝试说明如何在测试之间重置此状态,也许您可以根据自己的情况进行调整。
从基本的 "it's stored in memory" 示例开始
class StatementProcessorService {
// assuming you're storing state in memory for now
// here we're just creating a shared map, which is where we presume you're putting data
private Map<String, String> state = new HashMap<>();
}
最简单的方法是公开一种方法来从 StatementProcessorService
.
外部重置状态
class StatementProcessorService {
// ...
/** Reset state */
@VisibleForTesting
public void reset() { state.clear(); }
}
您还可以使用注入状态保持器,它在测试期间本身可以公开重置方法
class StateHolder {
// accessor/mutator methods
}
class TestStateHolder extends StateHolder {
// ...
public void reset() { ... }
}
class StatementProcessorService {
@Autowired
private StateHolder state;
}
最后,您可以使用 Mockito
模拟 StateHolder
@SpringBootTest
class StatementProcessorServiceTest {
@MockBean StateHolder state;
}
与 Spring 一样,有很多 种方法可以实现您的目标。
我认为我的问题与此问题有关: Tests pass when run individually but not when the whole test class run
我的测试都单独通过了,但是当我 运行 测试 class 时,其中两个失败了。调试显示 assertEquals 期望的状态与代码中给出的状态不同,主要是来自不同测试的状态。解决方案应该使用 @Before 或 @After 并进行清理,但我在使用它时遇到了麻烦,因为该实例是从 Spring.
自动装配的主要问题:我的想法是否正确,我如何'reset'自动装配实例?
@SpringBootTest
class StatementProcessorServiceTest {
@Autowired
StatementProcessorService statementProcessorService;
private StatementProcessorInputModel setup(long id, boolean endbalanceCorrect) {
StatementProcessorInputModel statementProcessorInputModel = new StatementProcessorInputModel();
statementProcessorInputModel.startBalance = 1.00;
statementProcessorInputModel.id= id;
statementProcessorInputModel.startBalance = 1.00;
statementProcessorInputModel.mutation = 1.00;
statementProcessorInputModel.endBalance = endbalanceCorrect ? 2.00 : 1.00;
return statementProcessorInputModel;
}
@Test
void verify_with_all_good_settings()
{
StatementProcessorResponseModel sut;
sut = statementProcessorService.validate(setup(1, true));
Assert.assertEquals(sut.result, "SUCCESSFUL");
}
@Test
void verify_with_good_settings_but_duplicated_reference()
{
StatementProcessorResponseModel sutFirst = statementProcessorService.validate(setup(2, true));
Assert.assertEquals(sutFirst.result, "SUCCESSFUL");
StatementProcessorResponseModel sutSecond;
sutSecond = statementProcessorService.validate(setup(2, true));
Assert.assertEquals(sutSecond.result, "DUPLICATE_REFERENCE");
}
@Test
void verify_with_wrong_endBalance_and_good_reference()
{
StatementProcessorResponseModel sut = statementProcessorService.validate(setup(3, false));
Assert.assertEquals(sut.result, "INCORRECT_END_BALANCE");
}
@Test
void verify_with_all_wrong_settings()
{
StatementProcessorResponseModel sutFirst = statementProcessorService.validate(setup(4, true));
Assert.assertEquals(sutFirst.result, "SUCCESSFUL");
StatementProcessorResponseModel sutSecond = statementProcessorService.validate(setup(4, false));
Assert.assertEquals(sutSecond.result, "DUPLICATE_REFERENCE_INCORRECT_END_BALANCE");
}
}
编辑 1:添加了服务代码
@Component
public class StatementProcessorService {
private StatementProcessorResponseModel responseModel = new StatementProcessorResponseModel();
private static ArrayList<Long> usedReferences = new ArrayList<>();
public StatementProcessorResponseModel validate(StatementProcessorInputModel inputModel){
if(!validateUniqueReference(inputModel.transactionReference))
{
responseModel.errorRecords.add("account_number_of_ inCorrectEndBalance _record");
responseModel.result = "DUPLICATE_REFERENCE";
}
if(!validateMutation(inputModel))
{
responseModel.errorRecords.add("account_number_of_ inCorrectEndBalance _record");
if (!responseModel.result.isBlank()){
responseModel.result = responseModel.result + "_INCORRECT_END_BALANCE";
}
else{
responseModel.result = "INCORRECT_END_BALANCE";
}
}
if (responseModel.result.isBlank()){
responseModel.result = "SUCCESSFUL";
}
return responseModel;
}
如果你标记你的测试 cases/classes 修改数据库 @Transactional
然后测试运行器将在测试后回滚事务。
您似乎没有使用数据库来存储状态,因此在不知道如何存储此状态的情况下很难添加完整的答案。不管 StatementProcessorService
必须以某种方式存储状态,所以我将尝试说明如何在测试之间重置此状态,也许您可以根据自己的情况进行调整。
从基本的 "it's stored in memory" 示例开始
class StatementProcessorService {
// assuming you're storing state in memory for now
// here we're just creating a shared map, which is where we presume you're putting data
private Map<String, String> state = new HashMap<>();
}
最简单的方法是公开一种方法来从 StatementProcessorService
.
class StatementProcessorService {
// ...
/** Reset state */
@VisibleForTesting
public void reset() { state.clear(); }
}
您还可以使用注入状态保持器,它在测试期间本身可以公开重置方法
class StateHolder {
// accessor/mutator methods
}
class TestStateHolder extends StateHolder {
// ...
public void reset() { ... }
}
class StatementProcessorService {
@Autowired
private StateHolder state;
}
最后,您可以使用 Mockito
模拟StateHolder
@SpringBootTest
class StatementProcessorServiceTest {
@MockBean StateHolder state;
}
与 Spring 一样,有很多 种方法可以实现您的目标。