在单元测试中使用JPA保存时没有结果



我在做一些单元测试时遇到了一个奇怪的情况。当我使用JPA的save方法时,它不会返回任何内容,也不会抛出任何错误。

@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class MerchantRepoTest {
private Long personID = 12333333l;
@Mock
private ABC abcRepo;
@Mock
private Person personRepo;
@Autowired
private TestEntityManager testEntityManager;
private Gson gson = new Gson();
@Test
public void testPerson() {
System.out.println("Starting................");
Person person = new Person();
TxnLimit txnLimit = new TxnLimit();
txnLimit.setType("MONTHY");
txnLimit.setValue(1000000000l);
List<TxnLimit> txnLimits = new ArrayList<>();
txnLimits.add(txnLimit);
person.setTxnLimits(gson.toJson(txnLimits));
ABC abc = new ABC();
abc.setPersonId(personId);
Metadata metaData = new Metadata();
metaData.setDescription("DESC");
metaData.setName("MUKUL");
person.setMetadata(metaData);
person.setId(personId);
person.setType("Food");
person.accountToken("hgh-hhjds-hdbhj");
try {
Person per1=  personRepo.save(merchant);
ABC savedA = abcRepo.save(abc);
Thread.sleep(1000);
System.out.println("SAVED @@@@@@@@@@@@@@@@@@");
System.out.println("ID1 + " + per1.getId());
System.out.println("###############");
}  catch (Throwable t) {
t.printStackTrace();
}
Person found = personRepo.findOne(personID);
System.out.println("FOUND..." + found);
String name = found.getMetadata().getName();
Assert.assertEquals(name, "MUKUL");
}
}

我的测试用例失败了,我在String name = found.getMetadata().getName();处得到了NullPointerException,因为我被发现为null。我试着打印中间的步骤,出乎意料的是,在保存细节的同时,出现了问题。

我可以打印System.out.println("SAVED @@@@@@@@@@@@@@@@@@");行,但在那行之后,我就无法打印下两行了。我在catch块中也没有得到任何异常。我在屏幕上看到的下一条消息是交易回滚。

2018-10-31 18:17:14.759 [] [] [Test worker] INFO  t.context.transaction.TransactionContext:106 - Began transaction (1) for test context [DefaultTestContext@780636f3 testClass = MerchantRepoTest, testInstance = com.paytm.paylite.merchant.repo.MerchantRepoTest@735dc46, testMethod = testOK1@MerchantRepoTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@8006101 testClass = MerchantRepoTest, locations = '{}', classes = '{class com.paytm.paylite.merchant.MerchantServiceApp}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@503407f6, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@73b73c3d, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@6bc7795, [ImportsContextCustomizer@4342f78e key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.SpringBootTestContextCustomizer@67aa907e, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@50394650, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@63f5badc, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@40ec0c87]; rollback [true]
Starting................
...
...
..
SAVED @@@@@@@@@@@@@@@@@@
FOUND...null
2018-10-31 18:17:15.829 [] [] [Test worker] INFO  t.context.transaction.TransactionContext:140 - Rolled back transaction for test: [DefaultTestContext@780636f3 testClass = MerchantRepoTest, testInstance = com.paytm.paylite.merchant.repo.MerchantRepoTest@735dc46, testMethod = testOK1@MerchantRepoTest, testException = java.lang.NullPointerException, mergedContextConfiguration = [WebMergedContextConfiguration@8006101 testClass = MerchantRepoTest, locations = '{}', classes = '{class com.paytm.paylite.merchant.MerchantServiceApp}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@503407f6, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@73b73c3d, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@6bc7795, [ImportsContextCustomizer@4342f78e key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.SpringBootTestContextCustomizer@67aa907e, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@50394650, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@63f5badc, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]]

我不知道这背后的原因是什么?

在单元测试中,自动连接personRepo和abcRepo是不明智的,嘲笑是可行的。在模拟这些类之后,您还应该模拟您使用的每个方法的行为。例如:

Mockito.when(personRepo.save(person)).thenReturn(person);

或者,如果不起作用,请尝试:

Mockito.when(personRepo.save(person)).thenAnswer(invocationOnMock -> {
Person p = (Person) invocationOnMock.getArguments()[0];
p.setId(1);
//create here object you expect to be returned by save method using setters.
return p;
});

把这些线放在试块之前。在谷歌上搜索如何在java单元测试中模拟,你可以找到很棒的例子等

发生这种情况是因为您的回购被嘲笑了。这意味着它的方法不会被调用。如果您真的想测试保存到DB,可以自动连接personRepoabcRepo(但您应该只为集成测试这样做(。单元测试的更好方法是通过when(abcRepo.findOne(any()).thenReturn(...);更改mock的行为。通过这种方式,您将测试测试类的行为,而不是精确地repo。

最新更新