Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法在spring启动测试中模拟persistenceContext_Java_Spring_Unit Testing_Jpa_Mockito - Fatal编程技术网

Java 无法在spring启动测试中模拟persistenceContext

Java 无法在spring启动测试中模拟persistenceContext,java,spring,unit-testing,jpa,mockito,Java,Spring,Unit Testing,Jpa,Mockito,我正在使用带有Mockito框架的spring引导测试来测试我的应用程序。其中一个存储库类EntityManager作为参考 我的班级看起来像下面 @Repository @Transactional @Slf4j public class SomeRepositoryService { @PersistenceContext private EntityManager entityManager; public

我正在使用带有Mockito框架的spring引导测试来测试我的应用程序。其中一个存储库类EntityManager作为参考

我的班级看起来像下面

    @Repository
    @Transactional
    @Slf4j
    public class SomeRepositoryService {

        @PersistenceContext
        private EntityManager entityManager;

        public List<Run> findBySearchCriteria(String searchCriteria,Integer 
 offset,Integer limit,Integer userId) {
        //code 
       }
    }
当我运行这个时,我会

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.jpa.repository.support.DefaultJpaContext]: Constructor threw exception; nested exception is java.lang.NullPointerException

    Caused by: java.lang.NullPointerException: null
        at org.springframework.data.jpa.repository.support.DefaultJpaContext.<init>(DefaultJpaContext.java:53) ~[spring-data-jpa-2.0.9.RELEASE.jar:2.0.9.RELEASE]
原因:org.springframework.beans.beans实例化异常:未能实例化[org.springframework.data.jpa.repository.support.DefaultJpaContext]:构造函数引发异常;嵌套异常是java.lang.NullPointerException
原因:java.lang.NullPointerException:null
在org.springframework.data.jpa.repository.support.DefaultJpaContext.(DefaultJpaContext.java:53)~[spring-data-jpa-2.0.9.RELEASE.jar:2.0.9.RELEASE]

有人能告诉我如何测试或解决此问题吗?

您可以使用
TestEntityManager
而不是模拟:

@Autowired
private TestEntityManager entityManager;
@Autowired
private RunRepositoryService runRepositoryService;

@Test
public void testFindBySearchCriteria() {
    // 1. Create needed objects and persist them using the test entity manager
    // 2. Test your repository method
}

您还需要使用
@DataJpaTest
注释您的测试,以使其正常工作

您可以使用JMockit轻松模拟用@PersistentContext注释的依赖项

@RunWith(JMockit.class)
public class RunRepositoryServiceTests {

@Mocked EntityManager entityManager; 

private RunRepositoryService runRepositoryService;

@Before
public void setup(){
    runRepositoryService = new RunRepositoryService();
    Deencapsulation.setField(runRepositoryService, entityManager); //because its a private field
}

@Test
public void testFindBySearchCriteria(@Mocked Query mockQuery) {
    //random fake values for input args
    String searchCriteria = "";
    Integer offset = 1;
    Integer limit = 2;
    Integer userId = 1;
    //fake object for output arg
    List<Run> runList = new ArrayList<Run>();
    new Expectations(){{
        entityManager.someMethodToMock(argumentMatchers);
        result = mockQuery;
        times = 1;
    //remaining expactations in your code, which will eventually return result
    }};

    //call method to test
    List<Run> result = runRepositoryService.findBySearchCriteria(searchCriteria, offset, limit, userId);

    //assertions
    assertEquals(runList, result);
}
}
@RunWith(JMockit.class)
公共类RunRepositoryServiceTests{
@模拟实体管理器实体管理器;
专用RunRepositoryService RunRepositoryService;
@以前
公共作废设置(){
runRepositoryService=新的runRepositoryService();
setField(runRepositoryService,entityManager);//因为它是一个私有字段
}
@试验
public void testFindBySearchCriteria(@Mocked Query mockQuery){
//输入参数的随机伪值
字符串searchCriteria=“”;
整数偏移=1;
整数极限=2;
整数userId=1;
//输出参数的伪对象
List runList=new ArrayList();
新期望(){{
entityManager.someMethodToMock(argumentMatchers);
结果=模拟查询;
次数=1;
//代码中剩余的表达式,最终将返回结果
}};
//调用方法进行测试
列表结果=runRepositoryService.findBySearchCriteria(搜索条件、偏移量、限制、用户ID);
//断言
assertEquals(运行列表、结果);
}
}

您可以在不使用
@DataJpaTest的情况下使用SpringRunner。这对我很有用:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {DataRepository.class, EntityManager.class, 
EntityManagerFactory.class})
public class DataRepositoryTest {

    @MockBean
    private EntityManager entityManager;

    @MockBean
    private EntityManagerFactory entityManagerFactory;

    @Autowired
    private DataRepository repository;

    @Before
    public void setup() {
        Mockito.when(entityManagerFactory.createEntityManager()).thenReturn(entityManager);
    }

    @Test
    public void resultTest() {

        Query q = mock(Query.class);
        when(q.setParameter(anyString(), any())).thenReturn(q);
        when(q.getResultList()).thenReturn(createMockReponse());

        when(entityManager.createQuery(anyString())).thenReturn(q);

        Result r = repository.callQuery();


    }

}

我遇到了一个类似的问题,为了解决这个问题,我不得不使用Springs ReflectionTestUtils来注入模拟:

@RunWith(SpringJUnit4ClassRunner.class)
public class RunRepositoryServiceTests {


    private EntityManager entityManagerMock; 


    @Autowired
    private RunRepositoryService runRepositoryService;

    @Before
    public void setUp () {
        entityManagerMock = Mockito.mock(EntityManager.class);
        ReflectionTestUtils.setField(runRepositoryService, "entityManager", entityManagerMock);
    }

    @Test
    public void testFindBySearchCriteria() {

        ....

        when(entityManagerMock.anyMethodToMock(anyObject())).thenReturn(...);

        ....

    }
}

您不能使用
@Autowired
。您需要在测试类中的RunRepositoryService上使用
@InjectMocks
。您可以在SpringBootTest中使用它。我试过了。很有效,谢谢。但是如果我不能得到一个基于Mockito的答案,我会接受的。试过了。。我得到了这个例外。。原因:java.lang.IllegalStateException:无法将数据源替换为用于测试的嵌入式数据库。如果您想要一个嵌入式数据库,请在类路径上放置一个受支持的数据库,或者调整@AutoConfigureTestDatabase的replace属性。
@RunWith(SpringJUnit4ClassRunner.class)
public class RunRepositoryServiceTests {


    private EntityManager entityManagerMock; 


    @Autowired
    private RunRepositoryService runRepositoryService;

    @Before
    public void setUp () {
        entityManagerMock = Mockito.mock(EntityManager.class);
        ReflectionTestUtils.setField(runRepositoryService, "entityManager", entityManagerMock);
    }

    @Test
    public void testFindBySearchCriteria() {

        ....

        when(entityManagerMock.anyMethodToMock(anyObject())).thenReturn(...);

        ....

    }
}