每次我尝试运行我的 Junit 测试用例时出现 NullPointer 异常
NullPointer Exception everytime I try to run my Junit Test Case
每次我尝试运行 junit 测试用例时,我都会遇到空指针异常,而且当我每次尝试处理函数 returns NULL 值时的异常。这是代码。
RestaurantRepository.java
package org.springsource.restbucks;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public interface RestaurantRepository extends PagingAndSortingRepository<Restaurant, Long> {
@Query("SELECT p FROM Restaurant p Where (p.id)=(:Id) and p.deleted=false")
Restaurant findById(@Param("Id") long Id);
@Query("SELECT p FROM Restaurant p Where LOWER(p.name)=LOWER(:name) and p.deleted = false")
Restaurant findByName(@Param("name") String name);
}
RestaurantController.java
@RestController
public class RestaurantController {
@Autowired
RestaurantRepository repository;
@RequestMapping(value = "/restaurants/{id}", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseEntity<Restaurant> getRestaurant(@PathVariable("id") long restaurantId) {
Restaurant responseRestaurant = repository.findOne(restaurantId);
if(responseRestaurant==null){
logger.error("No Restaurant found with id:"+restaurantId);
return new ResponseEntity<Restaurant>(HttpStatus.NOT_FOUND);
}else if(responseRestaurant.isDeleted()==true){
logger.error("Restaurant Object is deleted");
return new ResponseEntity<Restaurant>(HttpStatus.NOT_FOUND);
}else{
return new ResponseEntity<Restaurant>(responseRestaurant,HttpStatus.OK);
}
}
}
RestaurantRepositoryTest.java
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class RestaurantRepositoryTest{
@Autowired
private RestaurantRepository repository;
@Test
public void testfindById() throws Exception{ //testing findbyid method in restaurant repository
Restaurant responseRestaurant = repository.findByName("xyz"); //getting error over here
assertEquals("xyz",responseRestaurant.getName());
}
}
每当我运行 mvn test 时,我都会收到空指针异常。堆栈跟踪低于我在终端中显示的内容。
testfindById(org.springsource.restbucks.RestaurantRepositoryTest)
经过的时间:0.018 秒 <<< 错误! java.lang.NullPointerException:
在
处为空
org.springsource.restbucks.RestaurantRepositoryTest.testfindById(RestaurantRepositoryTest.java:19)
我应该怎么做才能成功运行我的测试?
你是 运行 作为没有 Spring 上下文的纯单元测试。因此,存储库不会自动装配。您应该能够通过在测试的顶部添加一些注释来解决这个问题 class.
如果使用 Spring 引导,那么像下面这样的东西应该可以工作,让 Spring 引导完成所有艰苦的工作:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
您也可以加载 Spring @Configuration
class 来初始化您的存储库(在我的例子中,这称为 DbConfig
),如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { DbConfig.class },
loader = AnnotationConfigContextLoader.class)
您的测试根本没有启动 Spring 上下文,因此完全忽略了注释。最好的解决方案是修改您的控制器 class 以将存储库作为构造函数参数,而不是使用字段注入。这允许您传入一个简单的模拟,例如 Mockito 模拟,并避免启动 Spring 上下文到 运行 单元测试的复杂性。
每次我尝试运行 junit 测试用例时,我都会遇到空指针异常,而且当我每次尝试处理函数 returns NULL 值时的异常。这是代码。
RestaurantRepository.java
package org.springsource.restbucks;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public interface RestaurantRepository extends PagingAndSortingRepository<Restaurant, Long> {
@Query("SELECT p FROM Restaurant p Where (p.id)=(:Id) and p.deleted=false")
Restaurant findById(@Param("Id") long Id);
@Query("SELECT p FROM Restaurant p Where LOWER(p.name)=LOWER(:name) and p.deleted = false")
Restaurant findByName(@Param("name") String name);
}
RestaurantController.java
@RestController
public class RestaurantController {
@Autowired
RestaurantRepository repository;
@RequestMapping(value = "/restaurants/{id}", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseEntity<Restaurant> getRestaurant(@PathVariable("id") long restaurantId) {
Restaurant responseRestaurant = repository.findOne(restaurantId);
if(responseRestaurant==null){
logger.error("No Restaurant found with id:"+restaurantId);
return new ResponseEntity<Restaurant>(HttpStatus.NOT_FOUND);
}else if(responseRestaurant.isDeleted()==true){
logger.error("Restaurant Object is deleted");
return new ResponseEntity<Restaurant>(HttpStatus.NOT_FOUND);
}else{
return new ResponseEntity<Restaurant>(responseRestaurant,HttpStatus.OK);
}
}
}
RestaurantRepositoryTest.java
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class RestaurantRepositoryTest{
@Autowired
private RestaurantRepository repository;
@Test
public void testfindById() throws Exception{ //testing findbyid method in restaurant repository
Restaurant responseRestaurant = repository.findByName("xyz"); //getting error over here
assertEquals("xyz",responseRestaurant.getName());
}
}
每当我运行 mvn test 时,我都会收到空指针异常。堆栈跟踪低于我在终端中显示的内容。
testfindById(org.springsource.restbucks.RestaurantRepositoryTest) 经过的时间:0.018 秒 <<< 错误! java.lang.NullPointerException: 在
处为空
org.springsource.restbucks.RestaurantRepositoryTest.testfindById(RestaurantRepositoryTest.java:19)
我应该怎么做才能成功运行我的测试?
你是 运行 作为没有 Spring 上下文的纯单元测试。因此,存储库不会自动装配。您应该能够通过在测试的顶部添加一些注释来解决这个问题 class.
如果使用 Spring 引导,那么像下面这样的东西应该可以工作,让 Spring 引导完成所有艰苦的工作:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
您也可以加载 Spring @Configuration
class 来初始化您的存储库(在我的例子中,这称为 DbConfig
),如下所示:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { DbConfig.class },
loader = AnnotationConfigContextLoader.class)
您的测试根本没有启动 Spring 上下文,因此完全忽略了注释。最好的解决方案是修改您的控制器 class 以将存储库作为构造函数参数,而不是使用字段注入。这允许您传入一个简单的模拟,例如 Mockito 模拟,并避免启动 Spring 上下文到 运行 单元测试的复杂性。