I am trying to test a spring boot application written completely in kotlin.
I am trying to test the Service layer mocking the repository object. Code is as bellow
#RunWith(MockitoJUnitRunner::class)
class TaskServiceTest {
#Mock
lateinit var taskRepository: TaskRepository
#InjectMocks
lateinit var taskService: TaskService
#Test
fun createNewTaskFailTest() {
val taskRequest = TaskRequest("fullName", "94123456789", "", "")
val newTask = Task(
id = null,
status = PENDING)
val savedTask = newTask.copy(id = 1L)
given(taskRepository.save(newTask)).willReturn(savedTask)
val createdTask = taskService.createTask(taskRequest)
Assert.assertEquals(createdTask.status, PENDING)
}
}
when I run this code I get the following error
java.lang.IllegalStateException: savedTask must not be null
at com.hsenid.servicestatusinquiry.service.TaskService.createTask(TaskService.kt:46)
at com.hsenid.servicestatusinquiry.service.TaskServiceTest.createNewTaskFailTest(TaskServiceTest.kt:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
[MockitoHint] TaskServiceTest.createNewTaskFailTest (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at com.hsenid.servicestatusinquiry.service.TaskServiceTest.createNewTaskFailTest(TaskServiceTest.kt:40)
[MockitoHint] ...args ok? -> at com.hsenid.servicestatusinquiry.service.TaskService.createTask(TaskService.kt:45)
create task is working fine when I call it from controller with http call
bellow is create task code sample
fun createTask(taskRequest: TaskRequest): Task {
val newTask = Task(
id = null,
status = PENDING)
val savedTask = repository.save(newTask)
return savedTask
}
how to fix this?
The following code worked for me
given(taskRepository.save(any(Task.class))).willReturn(savedTask)
I did this:
First I annotate my class with:
#ExtendWith(MockitoExtension::class)
class TaskServiceTest
Then:
private fun <T> anyObject(): T {
Mockito.anyObject<T>()
return uninitialized()
}
Mockito.`when`<Any>(taskRepository.save(anyObject()))
.thenReturn(validTask())
Worked for me.
A newbie to Spring boot running integration testing. Using exchange method of TestRestTemplate I am unable to pass LocalDateTime request params to test method. Here's my MemberController method and MemberControllerTest method. I guess it has to do with the date and format because the same exchange method works when I test for get member with id as integer.
#Test
#Transactional
public void getTopMembersss() throws Exception {
LocalDateTime startTime = LocalDateTime.of(2015, Month.JULY, 29, 19, 30, 40);
LocalDateTime endTime = LocalDateTime.of(2019, Month.JANUARY, 01, 19, 30, 40);
ResponseEntity<List<TopMemberDTO>> response = template.exchange(
"/api/member/top-member?startTime={startTime}&endTime={endTime}", HttpMethod.GET, null,
new ParameterizedTypeReference<List<TopMemberDTO>>() {
}, startTime.toString(), endTime.toString());
// , "2018-12-31T12:12:12", "2018-12-31T12:12:12"
Assert.assertEquals(200, response.getStatusCode().value());
}
#GetMapping(path = "/api/member/top-member?startTime={startTime}&endTime={endTime}")
public ResponseEntity<List<TopMemberDTO>> getTopMembers(
#RequestParam(value = "startTime", required = true) #DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime startTime,
#RequestParam(value = "endTime", required = true) #DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") LocalDateTime endTime) {
List<TopMemberDTO> topDrivers = new ArrayList<>();
/**
* Your Implementation Here.
*
*/
topDrivers = memberService.findTopMembersCount(startTime, endTime);
if (topDrivers.isEmpty()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(topDrivers);
}
}
java.lang.AssertionError: expected:<200> but was:<400>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at com.thankgod.controller.MemberControllerTest.getTopMembersss(MemberControllerTest.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
change
#GetMapping(path = "/api/member/top-member?startTime={startTime}&endTime={endTime}")
to
#GetMapping(path = "/api/member/top-member")
I am using SpringBoot 2.0.6-RELEASE
When I configure my api to use a CompletableFuture with no executor service provided - my tests run successfully. For example this tests passes ok
public Future<List<AlertsBodyVO>> getAlerts(#PathVariable(value = "userId") final String userId) {
return CompletableFuture.supplyAsync(() -> Service.getAlerts(userId));
}
#Test
public void testGetAlerts_NullResult() throws Exception {
String userId = "123456";
List<AlertsBodyVO> alertsVOList = null;
Mockito.when(mockService.getAlerts(Mockito.anyString())).thenReturn(alertsVOList);
MvcResult result = this.mockMvc.perform(get("/alerts/{userId}", userId)).andExpect(status().isOk())
.andReturn();
mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk())
.andExpect(jsonPath("$").doesNotExist())
.andReturn();
Mockito.verify(mockService, Mockito.times(1)).getAlerts(Mockito.anyString());
}
However - when I define my api to use an executorService as follows
public Future<List<AlertsBodyVO>> getAlerts(#PathVariable(value = "userId") final String userId) {
return CompletableFuture.supplyAsync(() -> Service.getAlerts(userId), executorService);
}
I get the following error
java.lang.IllegalStateException: Async result for handler [public java.util.concurrent.Future<java.util.List<com.domain.AlertsBodyVO>> com.controllers.API.getAlerts(java.lang.String)] was not set during the specified timeToWait=10000
at org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:146)
at org.springframework.test.web.servlet.DefaultMvcResult.getAsyncResult(DefaultMvcResult.java:136)
at org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch(MockMvcRequestBuilders.java:269)
at com.controllers.APITest.testGetAlerts_NullResult(APITest.java:207)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:78)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:84)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Any idea how I can get my MockMvc tests to pass when I specify the executorService to use?
It is difficult to used Mocked ExecuterService, because you should also mock all their behavior, like
Mockito.when(mockedExecuterService.execute...
And another hidden calls and processes inside of executor service.
Instead of that you can just create simple single thread executor for test purpose, i checked and it work correct with real ExecutorService (for example Executors.newSingleThreadExecutor()) and failed ofcouse with mocked. I think you now it how create test context - Spring Test Context
I am trying to implement tests in my spring boot app, but I have problems with ManyToOne/OneToMany links.
It seems that the link from the subobject is not created, while I use CascadeType = ALL.
I tried creating it in the BusinesDomain.addSubdomain, adding "subDomain.domain(this);" but this causes a loop.
I found out other topics with the same error but non of them seem to cover my issue.
Could you please help me find out what seems to be the issue ?
Thanks a lot!
Here are my Entities
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;
import lombok.experimental.Accessors;
#Accessors(fluent = true)
#Data
#Entity
#NoArgsConstructor
public class BusinessDomain {
#Setter(AccessLevel.NONE)
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#NonNull
#Column(unique=true)
private String name;
#OneToMany(mappedBy = "domain", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<BusinessSubDomain> subDomains = new LinkedHashSet<>();
public void addSubDomain(BusinessSubDomain subDomain) {
subDomains.add(subDomain);
}
}
#Accessors(fluent = true)
#Data
#Entity
#NoArgsConstructor
public class BusinessSubDomain {
#Setter(AccessLevel.NONE)
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#ManyToOne(optional = false)
#JoinColumn(name = "business_domain_id", referencedColumnName="id")
private BusinessDomain domain;
}
My service class:
#Override
public BusinessDomain saveOrUpdate(BusinessDomain businessDomain) throws OrcaException {
try {
BusinessDomain domain = businessDomainRepository.findByName(businessDomain.name());
if(null == domain) {
// Repository class not overriden (extends CrudRepository<BusinessDomain, Long>)
return businessDomainRepository.save(businessDomain);
} else {
domain.description(businessDomain.description());
domain.subDomains(businessDomain.subDomains());
return businessDomainRepository.save(domain);
}
} catch (Exception e) {
throw new OrcaException(e);
}
}
And my Test:
#RunWith(SpringRunner.class)
#SpringBootTest
public class BusinessDomainTest {
#Test
#Transactional
public void createBusinessDomainWithSubDomain() throws OrcaException {
BusinessDomain passengerBusinessDomain = new BusinessDomain().name(DOMAIN_NAME).description(DOMAIN_DESCRIPTION);
BusinessSubDomain distributionBusinessSubDomain = new BusinessSubDomain().name(SUBDOMAIN_NAME)
.description(SUBDOMAIN_DESCRIPTION);
passengerBusinessDomain.addSubDomain(distributionBusinessSubDomain);
businessDomainService.saveOrUpdate(passengerBusinessDomain);
BusinessDomain domain = businessDomainService.findByName(DOMAIN_NAME);
}
}
With this I get the error message:
[main] INFO
com.myproject.project.test.model.soadatamodel.business.domaining.BusinessDomainTest
- Started BusinessDomainTest in 24.161 seconds (JVM running for 26.159) [main] INFO org.springframework.test.context.transaction.TransactionContext -
Began transaction (1) for test context [DefaultTestContext#76480730
testClass = BusinessDomainTest, testInstance =
com.myproject.project.test.model.soadatamodel.business.domaining.BusinessDomainTest#405a296e,
testMethod = createBusinessDomainWithArea#BusinessDomainTest,
testException = [null], mergedContextConfiguration =
[WebMergedContextConfiguration#5f5c2451 testClass =
BusinessDomainTest, locations = '{}', classes = '{class
com.myproject.project.TestApplication}', contextInitializerClasses =
'[]', activeProfiles = '{}', propertySourceLocations = '{}',
propertySourceProperties =
'{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}',
contextCustomizers =
set[org.springframework.boot.test.context.SpringBootTestContextCustomizer#6eceb130,
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#47db50c5,
org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0,
org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0,
org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#68ceda24],
resourceBasePath = 'src/main/webapp', contextLoader =
'org.springframework.boot.test.context.SpringBootContextLoader',
parent = [null]]]; transaction manager
[org.springframework.orm.jpa.JpaTransactionManager#28d97205]; rollback
[true] [main] INFO
org.hibernate.hql.internal.QueryTranslatorFactoryInitiator -
HHH000397: Using ASTQueryTranslatorFactory Hibernate: select
businessdo0_.id as id1_1_, businessdo0_.description as descript2_1_,
businessdo0_.name as name3_1_ from BusinessDomain businessdo0_ where
businessdo0_.name=? Hibernate: call next value for hibernate_sequence
Hibernate: call next value for hibernate_sequence [main] WARN
org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 23502,
SQLState: 23502 [main] ERROR
org.hibernate.engine.jdbc.spi.SqlExceptionHelper - NULL not allowed
for column "BUSINESS_DOMAIN_ID"; SQL statement: insert into
BusinessSubDomain (description, business_domain_id, name, id) values
(?, ?, ?, ?) [23502-168] [main] INFO
org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl -
HHH000010: On release of batch it still contained JDBC statements
org.springframework.dao.DataIntegrityViolationException: could not
execute statement; SQL [n/a]; constraint [null]; nested exception is
org.hibernate.exception.ConstraintViolationException: could not
execute statement at
org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:278)
at
org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
at
org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:488)
at
org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at
org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy134.findByName(Unknown Source) at
com.myproject.project.service.soadatamodel.business.domaining.impl.BusinessDomainServiceImpl.findByName(BusinessDomainServiceImpl.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483) at
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy137.findByName(Unknown Source) at
com.myproject.project.test.model.soadatamodel.business.domaining.BusinessDomainTest.createBusinessDomainWithArea(BusinessDomainTest.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)Hibernate:
call next value for hibernate_sequence Hibernate: insert into
BusinessDomain (description, name, id) values (?, ?, ?) Hibernate:
insert into BusinessSubDomain (description, business_domain_id, name,
id) values (?, ?, ?, ?) could not execute statement; SQL [n/a];
constraint [null]; nested exception is
org.hibernate.exception.ConstraintViolationException: could not
execute statement
org.springframework.dao.DataIntegrityViolationException: could not
execute statement; SQL [n/a]; constraint [null]; nested exception is
org.hibernate.exception.ConstraintViolationException: could not
execute statement
at java.lang.reflect.Method.invoke(Method.java:483) at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at
org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20) at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at
org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
at
org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
at
org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at
org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
at
org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
at
org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
at
org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: org.hibernate.exception.ConstraintViolationException: could
not execute statement at
org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112)
at
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
at
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
at
org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2949)
at
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3449)
at
org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)
at
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)
at
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)
at
org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at
org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50)
at
org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1251)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1319) at
org.hibernate.internal.QueryImpl.list(QueryImpl.java:87) at
org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606) at
org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:529)
at
org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:54)
at
org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:206)
at
org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:85)
at
org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116)
at
org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106)
at
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
at
org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at
org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 56 more Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed
for column "BUSINESS_DOMAIN_ID"; SQL statement: insert into
BusinessSubDomain (description, business_domain_id, name, id) values
(?, ?, ?, ?) [23502-168] at
org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169) at
org.h2.message.DbException.get(DbException.java:146) at
org.h2.table.Column.validateConvertUpdateSequence(Column.java:293) at
org.h2.table.Table.validateConvertUpdateSequence(Table.java:689) at
org.h2.command.dml.Insert.insertRows(Insert.java:120) at
org.h2.command.dml.Insert.update(Insert.java:84) at
org.h2.command.CommandContainer.update(CommandContainer.java:75) at
org.h2.command.Command.executeUpdate(Command.java:230) at
org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:156)
at
org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483) at
org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
at com.sun.proxy.$Proxy130.executeUpdate(Unknown Source) at
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 84 more [main] INFO
org.springframework.test.context.transaction.TransactionContext -
Rolled back transaction for test context [DefaultTestContext#76480730
testClass = BusinessDomainTest, testInstance =
com.myproject.project.test.model.soadatamodel.business.domaining.BusinessDomainTest#405a296e,
testMethod = createBusinessDomainWithArea#BusinessDomainTest,
testException = [ERROR CODE : UNKNWN001] Unknown Error [Exception
:org.springframework.dao.DataIntegrityViolationException: could not
execute statement; SQL [n/a]; constraint [null]; nested exception is
org.hibernate.exception.ConstraintViolationException: could not
execute statement], mergedContextConfiguration =
[WebMergedContextConfiguration#5f5c2451 testClass =
BusinessDomainTest, locations = '{}', classes = '{class
com.myproject.project.TestApplication}', contextInitializerClasses =
'[]', activeProfiles = '{}', propertySourceLocations = '{}',
propertySourceProperties =
'{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}',
contextCustomizers =
set[org.springframework.boot.test.context.SpringBootTestContextCustomizer#6eceb130,
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#47db50c5,
org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0,
org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0,
org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#68ceda24],
resourceBasePath = 'src/main/webapp', contextLoader =
'org.springframework.boot.test.context.SpringBootContextLoader',
parent = [null]]]. [main] INFO
org.springframework.test.context.transaction.TransactionContext -
Began transaction (1) for test context [DefaultTestContext#76480730
testClass = BusinessDomainTest, testInstance =
com.myproject.project.test.model.soadatamodel.business.domaining.BusinessDomainTest#685e8e17,
testMethod = createSimpleBusinessDomain#BusinessDomainTest,
testException = [null], mergedContextConfiguration =
[WebMergedContextConfiguration#5f5c2451 testClass =
BusinessDomainTest, locations = '{}', classes = '{class
com.myproject.project.TestApplication}', contextInitializerClasses =
'[]', activeProfiles = '{}', propertySourceLocations = '{}',
propertySourceProperties =
'{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}',
contextCustomizers =
set[org.springframework.boot.test.context.SpringBootTestContextCustomizer#6eceb130,
org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#47db50c5,
org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0,
org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0,
org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#68ceda24],
resourceBasePath = 'src/main/webapp', contextLoader =
'org.springframework.boot.test.context.SpringBootContextLoader',
parent = [null]]]; transaction manager
[org.springframework.orm.jpa.JpaTransactionManager#28d97205]; rollback
[true]
Finally I understood.
First, the entity adder must be
public void addSubDomain(BusinessSubDomain subDomain) {
subDomains.add(subDomain);
subDomain.domain(this);
}
But this was causing an infinite loop with an infinite call to hash method.
I solved this (caused by lombok) using #Getter and #Setter instead of #Data in my entity.
Thanks
I am new to Spring boot and while testing the REST endpoint using SPOCK , came across with the question #24405727
I have tried the exact configuration but getting the below exception
java.lang.IllegalStateException: The WebApplicationContext for test context [TestContext#21a722ef testClass = HelloControllerSpec, testInstance = com.hello.HelloControllerSpec#63e68a2b, testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration#3479404a testClass = HelloControllerSpec, locations = '{}', classes = '{class com.Application}', contextInitializerClasses = '[]', activeProfiles = '{}', resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]] must be configured with a MockServletContext.
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:111)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:74)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.spockframework.spring.SpringTestContextManager.prepareTestInstance(SpringTestContextManager.java:49)
at org.spockframework.spring.SpringInterceptor.interceptSetupMethod(SpringInterceptor.java:42)
at org.spockframework.runtime.extension.AbstractMethodInterceptor.intercept(AbstractMethodInterceptor.java:28)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:84)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:48)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Below is my Groovy spock specification
#ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = Application.class)
#WebAppConfiguration
#IntegrationTest
class HelloControllerSpec extends Specification {
def "Greeting test"() {
when:
ResponseEntity entity = new RestTemplate().getForEntity("http://localhost:8080", String.class);
then:
entity.statusCode == HttpStatus.OK
}
}
Any help is highly appreciated.