Тесты Junit терпят неудачу из-за общих экземпляров (я думаю) - PullRequest
0 голосов
/ 05 мая 2020

Я думаю, что моя проблема связана с этой проблемой: Тесты проходят при индивидуальном запуске, но не при запуске всего тестового класса

Все мои тесты проходят индивидуально, но когда я запускаю тестовый класс , два из них терпят неудачу. Отладка показывает, что assertEquals ожидает состояний, отличных от заданных в коде, в основном состояний из разных тестов. Решение должно использовать @Before или @After и выполнить очистку, но у меня проблемы с этим, потому что экземпляр Autowired из Spring.

Главный вопрос: правильно ли я думаю и как мне сбросить 'экземпляр с автоматическим подключением?

@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;
    }

Ответы [ 2 ]

2 голосов
/ 05 мая 2020

Если вы пометите свои тестовые примеры / классы, которые изменяют базу данных, с помощью @Transactional, то средство выполнения теста откатит транзакцию после теста.

Вы можете обратиться к справочной документации относительно тестовых транзакций .

0 голосов
/ 05 мая 2020

Похоже, вы не используете базу данных для хранения состояния, поэтому сложно добавить полный ответ, не зная, как вы сохраняете это состояние. Независимо от того, что StatementProcessorService должен каким-то образом сохранять состояние, я попытаюсь проиллюстрировать, как вы можете сбросить это состояние между тестами, и, возможно, вы сможете адаптировать его к своей ситуации.

Начиная с базового c " он хранится в памяти "пример

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;
}

И, наконец, вы можете просто имитировать StateHolder с помощью Mockito

@SpringBootTest
class StatementProcessorServiceTest {
  @MockBean StateHolder state;
}

Как обычно в Spring, существует множество способов достижения вашей цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...