Hot questions for Using Mockito in jpa

Hot questions for Using Mockito in jpa

Question:

I am attempting to build a Spring Boot application, trying to stick to test driven development. My issue is that I have Spring Boot JPA included in my project but don't actually have a data source set up yet. Before adding the dependency, I was able to run my unit tests successfully.

Now that I have added the dependency, even attempting to execute my unit tests fails because it is unable to initialize a datasource for Spring Data.

I'm rather new to JUnit, Spring Boot and Mockito though. I want to be able to run my unit tests without actually having a datasource and instead mocking all of my repositories.

What is the proper way to do this?


Answer:

If you define some SQL engine commonly used for testing (e.g. HSQL, Derby or H2), Spring Boot should recognize it as test dependency and configure Datasource bean on top of it. In order to do that, just define such engine with test scope:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>

Problem will arise when you introduce production Datasource (e.g. Postgres or MySQL). At that state you would need to

  • configure testing Datasource explicitly with @Primary annotation
  • or provide testing configuration file (e.g. src/test/resources/application.properties) where H2 will be configured.

Question:

I'm creating a series of unit tests for an EJB application which uses JPA for the database persistence layer. As these are unit tests I'm treating the EJB beans as POJOs and using Mockito to mock the EntityManager calls.

The issue I've encountered is that one of the methods in my class under test changes a value in the entity before calling the EntityManager merge(...) method to save the entity, but I can't see how the unit test is able to check whether the method being tested did actually change the value.

Whilst I could add another when(...) method so that the merge(...) method returns an instance of the entity with the modified value, I don't think this would be of any benefit as it wouldn't actually test that the class under test had modified the value and would defeat the purpose of the test.

The method in my class under test is as follows:

public void discontinueWidget(String widgetId) {
    Widget widget = em.find(Widget.class, widgetId);
    //Code that checks whether the widget exists has been omitted for simplicity
    widget.setDiscontinued(true);
    em.merge(widget);
}

The code in my unit test is as follows:

@Mock
private EntityManager em;

@InjectMocks
private WidgetService classUnderTest;

@Test
public void discontinueWidget() {
    Widget testWidget = new Widget();
    testWidget.setWidgetName("foo");
    when(em.find(Widget.class, "foo")).thenReturn(testWidget);

    classUnderTest.discontinueWidget("en");

    //something needed here to check whether testWidget was set to discontinued

    //this checks the merge method was called but not whether the
    //discontinued value has been set to true
    verify(em).merge(testWidget ); 
}

As the Widget class isn't being mocked I can't call something along the lines of verify(testWidget).setDiscontinued(true);

My question is how can I check whether the discontinueWidget(...) method in the class under test has actually set the discontinued variable in the Widget class to true?

I'm using JUnit version 4.12 and Mockito version 1.10.19.


Answer:

You can declare the Widget in your test as being a mock also, and verify on it.

Widget testWidget = mock(Widget.class);
when(em.find(Widget.class, "foo")).thenReturn(testWidget);

classUnderTest.discontinueWidget("en");

//something needed here to check whether testWidget was set to discontinued
verify(testWidget).setDiscontinued(true);  

//this checks the merge method was called but not whether the
//discontinued value has been set to true
verify(em).merge(testWidget ); 

Question:

I have a test like this:

    @Test
    fun `can execute`() {
        whenever(countryRepository.findByIdOrNull("DE")).thenReturn(germany)
        underTest.execute()
    }

This test fails with the following error message:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Country cannot be returned by findById()
findById() should return Optional
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
   Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - 
   - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.

Pretty sure this might be an issue with Mockito as I am not using findbyId but using findByIdOrNull as this is more suitable for kotlin. I do not want to change the code to fix a test.

can you please help me with a way to get rid of this issue or to work around this?


Answer:

Apparently:

Mockito doesn't support the mocking of static methods, at least not in the near future. https://github.com/mockito/mockito/issues/1481

So the extension code is actually being executed rather than mocked.

One resolution may be to just let the code execute and instead of mocking findByIdOrNull just mock the underlying findById (to return an optional).

Edit

..or use MockK as the link suggests!

Question:

They are my methods and I am testing them: It is fine when I dont give null as parameter but I can not test when I give my parameter as null? I cant unterstand the logic of it.

Thats my converter methods:

 @Override
    public Integer convertToDatabaseColumn(WorkerId id) {
        if (Assert.isNull(id)) {
            return null;
        }
        return id.getValue();
    }

    @Override
    public WorkerId convertToEntityAttribute(Integer s) {
        if (Assert.isNull(s)) {
            return null;
        }
        return new WorkerId(s);
    }

and thats my test methods:

@Test
public void testConvertToDatabaseColumn() {
    WorkerId workerId = new WorkerId(1);
    Integer result = workerIdConverter.convertToDatabaseColumn(workerId);
    assertThat(result).isEqualTo(workerId.getValue());
}

@Test
public void testIfIdNull() {
    WorkerId workerId = null;
    Integer result = workerIdConverter.convertToDatabaseColumn(workerId);
    assertThat(result).isEqualTo(workerIdConverter.convertToDatabaseColumn(null));
}

Answer:

You don't need and should not invoke twice the method to test. That is enough :

@Test
public void testIfIdNull() {
    WorkerId workerId = null;
    Integer result = workerIdConverter.convertToDatabaseColumn(workerId);
    assertThat(result).isEqualTo(null);
}

Or more simply without matcher (that is not helpful here):

@Test
public void testIfIdNull() {
    WorkerId workerId = null;
    Integer result = workerIdConverter.convertToDatabaseColumn(workerId);
    Assert.assertNull(result);
}

And as the assertion and the method to test are concise, you could even write all in a single line without decreasing the readability:

@Test
public void testIfIdNull() {
    Assert.assertNull(workerIdConverter.convertToDatabaseColumn(null));
}

Question:

I'll send my methods an entity as their parameters, meaning that I have already the information I want to insert, update or delete from my database. I injected the entitymanager with my persistence unit name so i know it works, the name of my entitymanager is "em". I mapped my classes from my database with a database connection, the class that I'm working on is named by "TipoUsuario" These are my methods:

public void insert(TipoUsuario tipoUsuario) throws Exception {
    if (em != null) {
        em.persist(tipoUsuario);
    }
}

public void update(TipoUsuario tipoUsuario) throws Exception {
    if (em != null) {
        em.merge(tipoUsuario);
    }

}

public void delete(TipoUsuario tipoUsuario) throws Exception {
    if (em != null) {
        em.remove(tipoUsuario);
    }
}

I was working on the first method (insert) but I don't know how to test my method... This is my method to test insert method:

@Test
public void testInsert() throws Exception {
    System.out.println("insert");
    TipoUsuario tipoUsuario = new TipoUsuario(1, "Mantenedor", "AC2354", true);
    //Instance of my class where I have my insert, update and delete methods
    Utilidades instance = new Utilidades();
    //I mock an entity manager with annotation @Mock and I pass that mocked entitytmanager to my the entitymanager that I have in my main class 
    instance.em = this.em;
    //and that's all i got.. I don't know how to test if it really works
    //i send my entity to my methor insert
    instance.insert(tipoUsuario);
    //i dont know what is return o how to use the assertEquals in this case...
    assertEquals( ?,  ?);
}

I mocked the entitymanager because that's not part of my code and i know other have tested before,the only thing I want to test is if my method insert the information to the database.

I'll appreciate any idea that you may have.


Answer:

You can use

Mockito.verify(em, Mockito.times(1)).persist(tipoUsuario);

To see if the persist method was called 1 time.

Question:

I thought I understood difference between @Mock and @MockBean even I thought any object mocked never call real methods, Although when I run below test I can see basket has been inserted on hsqldb logs. So now I feel a bit confused about why basket is inserted when @Mock is used and not inserted when @MockBean is used.

INSERT INTO BASKET VALUES(5,'ABCDEFGHIJ','ACTIVE',1,'2019-01-18 12:00:36.066000','2019-01-18 12:00:36.066000')

In other hand if I do instead then hsqldb are clean. In both cases test is successfull.

@MockBean
private BasketRepository basketRepo;

Test class

@RunWith( SpringRunner.class )
@SpringBootTest( )
@ActiveProfiles( "test" )
public class BasketServiceTests
{

@SpyBean
private BasketService basketService;

@Mock
private BasketRepository basketRepo;

@Autowired
private UserAccountRepository userAccountRepo;

@Test
public void createBasketWithSameOrderRef() throws Exception
{
    UserAccount customer = userAccountRepo.findById( 1 )
            .orElseThrow( () -> new NotFoundException( "Customer not found" ) );

    Basket basket = new Basket();
    basket.setAudit( new Audit() );
    basket.setOrderRef( "ABCDEFGHIJ" );
    basket.setStatus( BasketStatusEnum.ACTIVE );
    basket.setUserAccount( customer );

    when( basketRepo.existsByOrderRef( anyString() ) ).thenReturn( false );
    when( basketRepo.save( isA( Basket.class ) ) ).thenReturn( basket );
    when( basketService.createOrderReference( ) ).thenReturn( "ABCDEFGHIJ" );

    Assert.notNull( basketService.getOrCreateByUserAccountBasket( customer ), "Basket id is null" );

}
}

Service

@Service
public class BasketService 
{
@Autowired
private BasketRepository basketRepo;

public Basket getOrCreateByUserAccountBasket( @NotNull final UserAccount userAccount )
{
    Optional<Basket> optBasket = basketRepo.findByUserAccountAndStatusActive( userAccount );

    if ( optBasket.isPresent() )
    {
        return optBasket.get();
    }

    String orderRef = null;

    do
    {
        orderRef = createOrderReference();
    }
    while( basketRepo.existsByOrderRef( orderRef ) );

    Basket basket = new Basket();
    basket.setAudit( new Audit() );
    basket.setOrderRef( orderRef );
    basket.setStatus( BasketStatusEnum.ACTIVE );
    basket.setUserAccount( userAccount );

    return basketRepo.save( basket );
}

public String createOrderReference()
{
    return RandomStringUtils.random( 10, true, false ).toUpperCase();
}
}

Answer:

@MockBean is a Spring annotation and is the one that should be used in integration tests in order to replace real bean with a mocked one:

Annotation that can be used to add mocks to a Spring ApplicationContext.

Mockitos @Mock creates a mock of that repository but does not inject that to the BasketService.

If you really need to used the Mockitos mocked version you would have to do it manually in the test:

@Mock
private BasketRepository basketRepo;

@Test
public void createBasketWithSameOrderRef() throws Exception
{
   basketService.setBasketRepository(basketRepo);
   ...

I wrote an article on Mockito Stubbing if you need a further read.

Question:

I have the following Service class with dynamic query.

public class CarService {

    public Page<Cars> getAllCars(CarRequest request, ,, String carCarrier, String carNumber,Pageable pageRequest){
       String userCarrier = request.getSubCarrier();
       Specification <Car> carSpecification = null;
       carSpecification = getCarDetails(request, carCarrier, carNumber);
       return carRepository.findAll(carSpecification, pageRequest);
   }

    public Specification<Car> getCarDetails(CarRequest request, String carCarrier, String carNumber) {
        System.out.println("I am in query");
        return (Root<Car> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
            System.out.println("I am executing query");
            List<Predicate> predicates = new ArrayList<>();
            if(StringUtils.isNotBlank(request.getCarColor())) {
                predicates.add(cb.and(cb.equal(root.get(“carColor”), request.getCarColor())));
            }

            if(StringUtils.isNotBlank(carCarrier)) {
                predicates.add(cb.and(root.get("carCarrier”),carCarrier)));
            }

            if(StringUtils.isNotBlank(carNumber)) {
                predicates.add(cb.and(cb.equal(root.get("carNumber"), carNumber)));

            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));

        };
    }
}

Below is my Test class where i am trying to test the dynamic query.

public class CarServiceTest {
@Mock
private CarService carService;

@Test
public void test_cars() {
    Pageable pageRequest = new PageRequest(0,20);
    CarRequest request = new CarRequest();
    request.setCarColor(“Red”);
    request.setCarMake(“Nissan”);
    when(carRepository.findAll(Mockito.any(Specification.class), Mockito.eq(pageRequest)))
            .thenReturn(Mockito.mock(Page.class));

    Assert.assertNotNull(carService.getAllCars(request, pageRequest));

    }

}

The above test case works but it just enters getCarDetails and prints the first line " I am in query" and returns. It does not go further ahead to check the conditional clauses in the query.

I also tried calling the method directly from test class as

carService.getCarDetails(carRequest. "ABC", “A123”);

Still the same result. I have recently started with Mockito so i am not sure if i am missing something here which is causing this behavior.

How can i make sure all my lines are executed from code coverage perspective.


Answer:

Specification is functional interface and you returning function which will be called by spring under the hood (after when you pass it to suitable repository method). In test you mock that repostiory method so there is no chance to execute that returned function.

In Specification case this function is called toPredicate()

https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/domain/Specification.java#L104

Question:

I am trying to write a unit test for a existing function that updates a value of a DB field using EntityManager. My unit test should verify that the class updates the value correctly. The current code looks like this:

public class MyClass {
    MyClass(EntityManager em) {
      this.em = em;
    }

    void updateValue() {
      em.getTransaction().begin();
      TypedQuery query = em.createQuery("select a from ...", MyResult.class);
      List<MyResult> results = query.getResultList(); 

      MyResult result = results.get(0);
      result.setInterestingValue(1);
      em.getTransaction().commit();
    }
}

My current approach for the unit testing:

@Mock EntityManager em;
@Mock TypedQuery query;

publid void test() {
   MyClass myClass = new MyClass(em);
   MyResult result = new MyResult();
   ArrayList<MyResult> resultList = new ArrayList<>();
   resultList.add(result);

   when(em.getTransaction()).thenReturn(mock(EntityTransaction.class));
   when(em.createQuery(anyString(), any())).thenReturn(query);
   when(query.getResultList()).thenReturn(resultList);

   myClass.updateValue();

   assertEquals(1, result.getInterestingValue());
}

My unit test above verifies that the MyResult instance is updated. However, it doesn't verify that the value is actually updated through EntityManager. In other words, I'd like to test if EntityManager is correctly used in the existing code. For example, even if I call commit() before setInterestinvValue(1), my test will still pass. Is there a good way to test it?


Answer:

As commented above, if you use mockito, the solution will be - use inOrder():

MyResult result = mock(MyResult.class);
EntityTransaction transaction = mock(EntityTransaction.class)

inOrder.verify(result).setInterestingValue(1);
inOrder.verify(transaction).commit();

Question:

I've an issue when I try to run the tests related to my Dao classes. It says that there's a syntax error when parsing my query. But why ?

Render.java :

@Entity
@Table(name = "ORR_RENDERS")
@NamedQueries({
    @NamedQuery(name = Render.FIND_RENDERS_AVAILABLE,
            query = "SELECT COUNT(r) Render r WHERE r.scene.id = :sceneId AND r.status = :status")
})
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "RENDER_TYPE")
@EntityListeners(EntityListener.class)
public abstract class Render extends AbstractORREntity {

public static final String FIND_RENDERS_AVAILABLE = "Render.findRendersAvailable";

@Id
@GeneratedValue(generator = "renderSeq")
@SequenceGenerator(name = "renderSeq", sequenceName = "ORR_REND_SEQ", allocationSize = 1)
@Column(name = "IDS")
private Long id;

@ManyToOne
@NotNull(message = "The scene cannot be null.")
@JoinColumn(name = "SCEN_IDS", referencedColumnName = "IDS", nullable = false)
private Scene scene;

@NotNull(message = "The status cannot be null.")
@Enumerated(EnumType.STRING)
@Column(name = "STATUS")
private RenderStatus status;

RenderDaoImpl.java method :

    @Override
public Long findAmountOfRendersAvailableForScene(Long sceneId) {
    return entityManager.createNamedQuery(Render.FIND_RENDERS_AVAILABLE, Long.class)
            .setParameter("sceneId", sceneId)
            .setParameter("status", RenderStatus.DONE)
            .getSingleResult();
}

RenderStatus.java

public enum RenderStatus {

   DONE,
   NOT_REQUESTED,
   WAITING,
   IN_PROGRESS,
   FAILED
}

StackTrace

javax.persistence.PersistenceException: Exception [EclipseLink-8024] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing the query [Render.findRendersAvailable: SELECT COUNT(r) Render r WHERE r.scene.id = :sceneId AND r.status = :status], line 1, column 23: syntax error at [r].
Internal Exception: MismatchedTokenException(78!=32)

at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:397)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:151)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:207)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:195)
at com.agc.test.common.persistence.PersistenceTestCase.createEntityManager(PersistenceTestCase.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56)
at java.lang.reflect.Method.invoke(Method.java:620)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:300)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:288)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:208)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:121)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:123)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)

Due to this error, I also have a NullPointerException because it seems like my entityManager is not retrievable :

java.lang.NullPointerException
at com.agc.test.common.persistence.PersistenceTestCase.getTransaction(PersistenceTestCase.java:132)
at com.agc.test.common.persistence.PersistenceTestCase.after(PersistenceTestCase.java:254)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56)
at java.lang.reflect.Method.invoke(Method.java:620)
at org.junit.internal.runners.MethodRoadie.runAfters(MethodRoadie.java:149)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:101)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:300)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:288)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:208)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:121)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:123)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)

Answer:

Your From is missing.

SELECT COUNT(r) Render r WHERE r.scene.id = :sceneId AND r.status = :status

Should be something like

SELECT COUNT(r) FROM Render r  WHERE r.scene.id = :sceneId AND r.status = :status

Question:

I was having some problem when trying to create a junit test cases for delete with JPA. In my service class, I am using the default function provided by JPA:

public void delete(Long id) {
        log.debug("Request to delete Enroll : {}", id);
        enrollRepository.deleteById(id);
}

Then my unit test, I am trying to mock an object and then perform the deletion:

@Test
public void testDeleteEnrollExpectSuccess() {
    Enroll enroll = prepareEnrollWithBedAllocation();
    enrollService.delete(enroll.getId());
    verify(enrollRepository, times(1)).delete(enroll);
}

I am tyring to mock the enroll object like this:

private Enroll prepareEnrollWithBedAllocation() {
    LocalDateTime localDateTime = LocalDateTime.now();
    ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("UTC"));

    Enroll enroll = new Enroll();
    enroll.setId(new Long(1));
    enroll.seteDate(zonedDateTime);
    enroll.setEbStartdt(zonedDateTime);
    enroll.setEbEnddt(zonedDateTime);
    enroll.setBed(prepareBed());
    enroll.setPatient(preparePatient());
    enroll.setDoc(prepareDoc());
    enroll.seteCondition("Normal");
    return enroll;
}

However, I am getting these error messages and my test case was failed:

Wanted but not invoked:
enrollRepository.delete(
    Enroll{id=1, eCondition='Normal', eRemarks='null', ebStartdt='2019-04-09T16:40:32.703Z[UTC]', ebEnddt='2019-04-09T16:40:32.703Z[UTC]', eDate='2019-04-09T16:40:32.703Z[UTC]'}
);
-> at com.team.generated.service.EnrollServiceTest.testDeleteEnrollExpectSuccess(EnrollServiceTest.java:61)

However, there was exactly 1 interaction with this mock:
enrollRepository.deleteById(1L);
-> at com.team.generated.service.EnrollService.delete(EnrollService.java:74)

Any idea? Thanks!


Answer:

The error says for itself: you're verifing the method delete(Long id):

verify(enrollRepository, times(1)).delete(enroll);

However, your service object invokes deleteById() method:

enrollRepository.deleteById(id);

I think you want to do this:

@Test
public void testDeleteEnrollExpectSuccess() {
    Enroll enroll = prepareEnrollWithBedAllocation();
    enrollService.delete(enroll.getId());
    verify(enrollRepository, times(1)).deleteById(enroll.getId());
}