Как написать тестовые случаи JUnit с игнорированием действий базы данных - PullRequest
0 голосов
/ 13 ноября 2018

Ниже приведен мой тестовый класс

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/ds-context.xml")
@WebAppConfiguration
public class PaidListTest {

    @Autowired
    PaymentService paymentService;

    @Test
    public void getPaidList() {
        List<PaymentGetServiceDO> response = null;
        try {
            response = paymentService.setPaidStatusList();          
            if(response != null && response.size() > 0){
                for(int i = 0; i < response.size(); i++){
                    assertNotNull(response.get(i).getAgentcode());
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

На уровне DAO служебного вызова paymentService.setPaidStatusList () выполняет некоторые операции с базами данных операций сохранения и обновления, например em.merge(renewalPoliciesDO);
Но я не хочу выполнять их при вызове тестового метода, их нужно вызывать только при вызове реальной бизнес-логики.
Как я могу ограничить или откатить транзакции базы данных здесь?
Сервис и методы DAO здесь утомительны.Однако я упростил их для справки.
Метод обслуживания if(!updateList.isEmpty()){ HashMap<String,String> recordset = new HashMap<String,String>(); recordset = paymentDAO.setRenewalStatus(updateList); }
Реализация DAO

if(paymentUpdateResDO.getPaymentstatus().equalsIgnoreCase("MANUAL") && 
!responseUpdateStatus.getPolicystatusid().equals(renewedStatusId)){
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Integer> payQuery = criteriaBuilder.createQuery(Integer.class);
Root<PaymentStatusDO> payRoot = payQuery.from(PaymentStatusDO.class);
payQuery.multiselect(payRoot.get("paymentstatusid"));
payQuery.where(criteriaBuilder.equal(payRoot.get("paymentstatusdescription"), "Manual"));
Integer paymentStatusId = em.createQuery(payQuery).getSingleResult();
insertOldPolicy(responseUpdateStatus);
responseUpdateStatus.setNewpolicyno(paymentUpdateResDO.getNewpolicyno());
responseUpdateStatus.setPreviousstatusid(responseUpdateStatus.getPolicystatusid());
responseUpdateStatus.setPolicystatusid(renewedStatusId);
Timestamp modifiedDate = new Timestamp(System.currentTimeMillis());
responseUpdateStatus.setModifieddatetime(modifiedDate);
responseUpdateStatus.setModifiedby("RPA");
responseUpdateStatus.setPaymentstatusid(paymentStatusId);
responseUpdateStatus.setActiveindicator("Y");
em.merge(responseUpdateStatus);
successRecords++;
}

В моем случае мне нужны массивы результатов, но действия em.merge и em.persist необходимо игнорировать.

Когда я пытаюсь использовать MockitoJUnitRunner как @GauravRai1512 предпочтительно, я выполняю свой тестовый сценарий, но программа завершается, поэтому я не могу получить результат ArrayLists.

Screenshot for successful execution of testcase
См. этоизображение Program terminated, so that nothing got executed

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

Вы должны следовать нижеприведенному подходу, предложенному Пуджей Аггарвалем.

import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

    @RunWith(MockitoJUnitRunner.class)
    public class PaidListTest {

        @Mock
        PaymentService paymentService;

        @Before
          public void setUp() {
             MockitoAnnotations.initMocks(this);
             mapperObj = new ObjectMapper();
             List<PaymentGetServiceDO> response = new ArrayList<PaymentGetServiceDO>();
}
        @Test
        public void getPaidList() {
            List<PaymentGetServiceDO> response = null;
            try {
                response = paymentService.setPaidStatusList();          
                if(response != null && response.size() > 0){
                    for(int i = 0; i < response.size(); i++){
                        assertNotNull(response.get(i).getAgentcode());
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

Этот код не выполнит операцию сохранения и обновления.

0 голосов
/ 13 ноября 2018

Как и другие говорили, вы можете:

  • Перемешайте PaymentService, чтобы вы могли точно определить, что делать при каждом вызове. В этом случае вы просто возвращаете жестко запрошенный ответ List<PaymentGetServiceDO>, и ваш тест может что-то с этим сделать. Недостатком этого является то, что вы не действительно тестируете PaymentService в этом случае. Вы просто смотрите на жестко закодированные данные и что-то делаете с ними. На мой взгляд, это недопустимый тест.

  • Или вы можете создать экземпляр объекта PaymentService либо с базой данных в памяти, только для использования с тестами, либо с фиктивным объектом БД, где вы затем сможете точно определить, как реагировать на каждый из merge, save, update и аналогичные операции. Если объект PaymentService не позволяет этого, то его следует изменить, чтобы он принимал в качестве параметра базу данных / соединение, который будет обычным введенным параметром @Autowired при работе в рабочей среде, но который можно создать вручную, когда тестирование. Это было бы правильным тестом, так как вы проверяли бы остальную часть логики внутри setPaidStatusList, но на самом деле вы не обращаетесь к базе данных, чтобы достичь этого.

0 голосов
/ 13 ноября 2018

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

Вы можете научиться писать тестовые примеры jmockit из http://jmockit.github.io/tutorial/Introduction.html

Или

https://winterbe.com/posts/2009/08/18/introducing-jmockit/

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