always entityManager = null - spring

I can’t test entityManager in unit test
#PersistenceContextprivate EntityManager entityManager;
always entityManager = null
#Repository
public class IRepositoryImpl {
#PersistenceContext
private EntityManager entityManager;
public I findI(){
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
....
}
....
}
The unit test:
private IRepositoryImpl iRepositoryImpl ;
#Test
void findITest(){
I i = iRepositoryImpl.findI();
...
}
java.lang.NullPointerException
entityManager = null

You need to add below in your unit test class:
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SpringBootApplicationClass.class) //annotation when you need Spring Boot features

Related

#ExpectedDatabase does not recognize deleted entity with MockMvc

I am having trouble using the #ExpectedDatabase annotation from springtestdbunit:
#SpringBootTest
#Transactional
#AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
#TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
TransactionDbUnitTestExecutionListener.class
})
#AutoConfigureMockMvc
class GroupControllerIntegrationTest {
#Autowired private MockMvc mvc;
#PersistenceContext private EntityManager entityManager;
#Test
#DatabaseSetup(value = "/createTwoGroups.xml")
#ExpectedDatabase(value = "/createSingleGroup.xml", table = "groups")
void givenGroups_deleteById_assert() throws Exception {
mvc.perform(delete("/groups/{id}", 1L))
.andDo(print())
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("/groups"))
.andExpect(model().hasNoErrors())
.andExpect(flash().attribute("message", "Gruppe erfolgreich gelöscht."));
// TODO: not working
// necessary due to:
// https://github.com/springtestdbunit/spring-test-dbunit/issues/75
entityManager.flush();
}
}
I receive
java.lang.Exception: org.dbunit.assertion.DbComparisonFailure[value (table=groups, row=0, col=id)expected:<1>but was:<2>]
As my comment in the integration test points out, the issue seems to be known. However, the suggested workaround with entityManager.flush() does not work with MockMvc.

Jpa Auditing test null in getCreatedBy, and getLastModifiedBy

Hi I am trying to write unit test for Auditing
#DataJpaTest
#EnableJpaAuditing
#RunWith(SpringRunner.class)
#AutoConfigureEmbeddedDatabase(type=POSTGRES)
public class MyTestAuditor {
#Autowired
private TestEntityManager entityManager;
#Test
public void auditTest() throws InterruptedException {
final MyEntity testEntity = MyEntity.builder()
....
.build();
SLOEntity entity = entityManager.persistAndFlush(testEntity);
assertNotNull(testEntity.getCreatedOn());
assertNotNull(testEntity.getLastModifiedOn());
assertNotNull(testEntity.getCreatedBy());
assertNotNull(testEntity.getLastModifiedBy());
}
}
I pass first two assertion, the timestamp ones, but fail the username part. Is there anything I am missing here, thanks:)

Mockito injecting mocks Spring Boot test

Hi I have a service class that contains mapper and repository:
#Service
public class ProductServiceImp implements ProductService {
#Autowired
private ProductRepository repository;
#Autowired
private WarehouseApiMapper mapper;
public ProductServiceImp(ProductRepository repository) {
this.repository = repository;
}
}
Repository:
#Repository
public interface ProductRepository extends JpaRepository<Product, Integer> {
}
Mapper:
#Mapper(componentModel = "spring")
public interface WarehouseApiMapper {
WarehouseApiMapper mapper = Mappers.getMapper(WarehouseApiMapper.class);
Product ProductDtoToProduct(ProductDto productDto);
ProductDto ProductToProductDto(Product product);
}
In test class I would like to inject mock repository and autowired mapper
Here is my test class:
#SpringBootTest
public class ProductServiceTest {
#Mock
ProductRepository repository;
#InjectMocks
ProductServiceImp service;
#ParameterizedTest
#MethodSource("provideParametersProductUpdate")
void assert_that_product_is_updated_correctly(String productName, BigDecimal productPrice) {
Product oldProduct = new Product("Product that does not exist", BigDecimal.valueOf(1000000), null);
oldProduct.setId(1);
Mockito.when(repository.findById(1)).thenReturn(Optional.of(oldProduct));
Product newProduct = new Product(productName, productPrice, null);
newProduct.setId(1);
ProductDto updatedProduct = service.updateProduct(newProduct);
Assertions.assertEquals(productPrice, updatedProduct.getPrice());
Assertions.assertEquals(productName, updatedProduct.getName());
}
private static Stream<Arguments> provideParametersProductUpdate() {
return Stream.of(
Arguments.of("dark chocolate", BigDecimal.valueOf(3.2)),
Arguments.of("chewing gum", BigDecimal.valueOf(1.2)),
Arguments.of("lollipop", BigDecimal.valueOf(4.0))
);
}
}
Code throws NullPointerException when is trying to map object in service method.
Somebody knows how can I inject this? Thanks for ur answers
If you want to create just a Mockito test you could use the annotation #RunWith(MockitoJUnitRunner.class) instead of #SpringBootTest.
But if you want to create a Spring Boot integration test then you should use #MockBean instead of #Mock and #Autowired instead of #InjectMocks.

How to mock JPA for Post method using mockito

Im trying to write the Unit test for a Create(Post) method which uses the JPA as DAO Layer .Im new to Mockito , hence insights needed .
1.EmployeeService .java
#Component("IEmployeeService ")
public class EmployeeService implements IInputService {
#Inject
EntityManagerFactory emf;
#PersistenceContext
EntityManager em;
public InputEntity create(InputEntity inputEntity) {
em = emf.createEntityManager();
try {
em.getTransaction().begin();
inputEntity.setLST_UPDTD_TS(new Date());
inputEntity.setLST_UPDTD_USER_ID(new String("USER1"));
em.persist(inputEntity);
em.getTransaction().commit();
} catch (PersistenceException e)
{
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
throw new WebApplicationException(e,Response.Status.INTERNAL_SERVER_ERROR);
}
finally {
em.close();
}
return inputEntity;
}
2.InputEntity.java is the Entity class with getters and setters for corresponding columns to employee age,salary ,etc .
Now if a Post method is called ,the create method in the EmployeeService class will be invoked .I have to write a unit test using mockito , and i m getting null-pointer , below is the test i wrote .
#Category(UnitTest.class)
#RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceTest {
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
#Autowired
EmployeeService employeeService;
#Mock
InputEntity inputEntity;
#Mock
EntityManagerFactory emf;
#Mock
private EntityManager em;
#Mock
private EntityTransaction et;
#Rule
public ExpectedException expectedException = ExpectedException.none();
#Test
public void test_create_employee_success() throws Exception {
InputEntity expected = Mockito.mock(InputEntity .class);
Mockito.when(em.getTransaction()).thenReturn(et);
Mockito.when(emf.createEntityManager()).thenReturn(em);
Mockito.doReturn(expected).when(employeeService).create(inputEntityMock);
InputEntity actual = new InputEntity();
Mockito.doReturn(actual).when(employeeService).create(inputFileRoleValidationMock);
assertEquals(expected, actual);
}
You have a local mock expected, that you are attempting to use in an assertEquals(), but that will never work because assertEquals uses Object.equals, and Mockito hijacks equals for internal uses. A Mockito mock will never Object.equals anything except itself.
We had the similar problem of NullPointerException and it was because of the entity manager. After we updated the connection properties in setUp method, we could able to call the JPA.
You can try to set the connection properties something like this.
//declare emfactory
private static EntityManagerFactory emfactory;
private static EntityManager em;
#BeforeClass
public static void setUp() throws Exception{
Map<Object, Object> properties = new HashMap<Object, Object>();
properties.put("openjpa.ConnectionURL",
"jdbc:db2://yourserver:port/DBName");
properties.put("openjpa.ConnectionUserName", "username");
properties.put("openjpa.ConnectionPassword", "userpassword");
//set Schema
//set Driver Name
emfactory = Persistence.createEntityManagerFactory("PersistenceUnitName",
properties);
em = emfactory.createEntityManager();
Mockito.when(emf.createEntityManager()).thenReturn(em);
}
Plus you need to modify your test_create_employee_success() to make this working. You are mocking everything in this method, which you should not do. You can try something like this.
#Test
public void test_create_employee_success() throws Exception {
{
InputEntity inputEntity = new InputEntity();
employeeService.create(inputEntity);
}
You need following changes in the code:
1.Instead of
#Autowired
EmployeeService employeeService;
You can use:
#InjectMocks
private EmployeeService EmployeeService;
Also as you are mocking in the method - InputEntity expected = Mockito.mock(InputEntity .class); you dont need at this declaration at the class level unless it is used in some other methods.
Also you can get rid of the declaration -
InputEntity actual = new InputEntity();
You can not assert mocked object and object using new keyword for equality.
Clean unit test will look like this -
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceImplTest {
#Mock
private EntityManager em;
#Mock
private EntityManagerFactory emf;
#InjectMocks
private EmployeeService EmployeeService;
#Mock
private EntityTransaction et;
#Test
public void testCreate() throws Exception {
InputEntity expected = Mockito.mock(InputEntity.class);
Mockito.when(em.getTransaction()).thenReturn(et);
Mockito.when(emf.createEntityManager()).thenReturn(em);
EmployeeService.create(expected);
Mockito.verify(em, Mockito.times(1)).persist(expected);
}
}

#Rollback in TestNG Integration Test but entry in DB committed

#ContextConfiguration(classes = { ServiceConfig.class,PersistenceConfiguration.class, MailConfig.class })
#Transactional
public class CreateStatsIT extends AbstractTestNGSpringContextTests {
#Autowired
private UserRepository userRepository;
#Test
#Rollback
#Transactional
public void insertUserIT() {
User u = new User(1L, "Test");
u = userRepository.save(s);
List<User> us = userRepository.findAll();
System.out.println(us.size());
}
}
I would expect that the user would not be present in the database after the completion of the test but it is. The Spring Integration Tests documentation describes that the tests rollback automatically and also that #Rollback does not let the transaction be committed.
What am I doing wrong?

Resources