Java 单元测试使用DB休眠,测试返回nullpointerexception

Java 单元测试使用DB休眠,测试返回nullpointerexception,java,hibernate,unit-testing,spring-boot,mockito,Java,Hibernate,Unit Testing,Spring Boot,Mockito,我用ORM(Hibernate)编写了RESTAPI,现在我想测试该服务逻辑。 我试图模仿我的数据库的实体,但我并没有惊人的结果。 我的选择是和莫基托一起得到这个,但现在我对此有所怀疑。 通常我会从我编写的测试中得到NullPointerException。我应该用另一种方式编写Junit测试(不同于“模拟”那个DB的方式)还是不理解Hibernate 这是我的密码: 测试班 public class ItemServiceImplTest { @Spy private ItemService

我用ORM(Hibernate)编写了RESTAPI,现在我想测试该服务逻辑。 我试图模仿我的数据库的实体,但我并没有惊人的结果。 我的选择是和莫基托一起得到这个,但现在我对此有所怀疑。 通常我会从我编写的测试中得到NullPointerException。我应该用另一种方式编写Junit测试(不同于“模拟”那个DB的方式)还是不理解Hibernate

这是我的密码: 测试班

public class ItemServiceImplTest {

@Spy
private ItemServiceImplementation itemServImpl;

@Mock
private BasketRepository basketRepository;
@Mock
private ItemRepository itemRepository;
@Mock
private Basket basket;
@Spy
private Item item;

@Before
public void setupMock() {

    MockitoAnnotations.initMocks(this);
    itemServImpl = new ItemServiceImplementation();
    itemServImpl.setItemRepository(itemRepository);
    itemServImpl.setBasketRepository(basketRepository);

}


@Test
public void testShowBasket() {
    Iterable<Basket> element = basketRepository.findAll();

    when(itemServImpl.showBasket()).thenReturn(element);

    Iterable<Basket> elementOne = itemServImpl.showBasket();

    assertThat(elementOne, is(equalTo(element)));
}


@Test
public void testAddToBasketStringInt() {
    Item a = new Item("A", 40, 70, 3);
    Basket testObjOne = new Basket(3, 70, a);

    when(itemServImpl.addToBasket("A", 3)).thenReturn((Iterable<Basket>) basketRepository.save(testObjOne));

    Iterable<Basket> zzz = itemServImpl.addToBasket("A", 3);

    assertThat(zzz, is(equalTo(testObjOne)));
}
服务

@Service("itemService")
@Transactional
public class ItemServiceImplementation implements ItemCRUDService, ItemCostService, ItemFindService {



public static final Logger logger = LoggerFactory.getLogger(ItemServiceImplementation.class);

@Autowired
public void setItemRepository(ItemRepository itemRepository) {
    this.itemRepository = itemRepository;
}
@Autowired
public void setBasketRepository(BasketRepository basketRepository) {
    this.basketRepository = basketRepository;
}

private BasketRepository basketRepository;

private ItemRepository itemRepository;


public Iterable<Basket> showBasket() {

    return basketRepository.findAll();
}


public Iterable<Basket> addToBasket(String name, int qty) {

        if (basketRepository.exists(itemRepository.findOne(findItem(name).getId()).getId())==false) { 

        logger.info("add to empty list");
        basketRepository.save(new Basket(qty, itemCost(name, qty), findItem(name)));
        logger.info("adding");
    }

    modifyOrder(findItem(name).getId(), qty);
    itemCost(name, qty);
    logger.info("modify");

    return showBasket();

}
public Item findItem(String name) {

    for (Item item : itemRepository.findAll()) {
        if (item.getName().equals(name)) {
            return item;
        }
    }
    return null;
}
public int itemCost(String name, int qty) {

    int price = 0;

    int modulo = qty % findItem(name).getSpecialPrice();

    price = findItem(name).getPrice() * modulo
            + findItem(name).getSpecialPrice() * ((qty - modulo) / `findItem(name).getSpecialPrice());`

    return price;

}
@Service(“itemService”)
@交易的
公共类ItemServiceImplementation实现ItemCRUDService、ItemCostService、ItemFindService{
公共静态最终记录器Logger=LoggerFactory.getLogger(ItemServiceImplementation.class);
@自动连线
public void setItemRepository(ItemRepository ItemRepository){
this.itemRepository=itemRepository;
}
@自动连线
公共存储库BasketRepository(BasketRepository BasketRepository){
this.basketRepository=basketRepository;
}
私人篮球知识库篮球知识库;
私有项目存储库项目存储库;
公众可阅读展示篮(){
return basketRepository.findAll();
}
公共Iterable addToBasket(字符串名称,整数数量){
如果(basketRepository.exists)(itemRepository.findOne(findItem(name).getId()).getId())==false){
logger.info(“添加到空列表”);
basketRepository.save(新篮子(数量、项目成本(名称、数量)、findItem(名称));
logger.info(“添加”);
}
修改订单(findItem(name).getId(),数量);
项目成本(名称、数量);
logger.info(“修改”);
返回展示篮();
}
公共项findItem(字符串名称){
对于(项:itemRepository.findAll()){
if(item.getName().equals(name)){
退货项目;
}
}
返回null;
}
公共整数项成本(字符串名称,整数数量){
国际价格=0;
整数模=数量%findItem(名称).getSpecialPrice();
price=findItem(name).getPrice()*模
+findItem(名称).getSpecialPrice()*((数量-模)/`findItem(名称).getSpecialPrice())`
退货价格;
}
我是否应该以另一种方式编写Junit测试(与“mock”不同) (该DB)

您没有提到在生产中使用的是什么数据库,但是如果它是传统的基于SQL的数据库,那么很可能您可以在单元测试的兼容模式中使用或嵌入数据库(如果您将嵌入式连接设置为默认spring概要文件的数据源,我发现这是最简单的方法)

我是否应该以另一种方式编写Junit测试(与“mock”不同) (该DB)


您没有提到在生产中使用的是什么数据库,但是如果它是传统的基于SQL的数据库,那么很可能您可以在单元测试的兼容模式中使用或嵌入数据库(如果您将嵌入式连接设置为默认spring概要文件的数据源,我发现这是最简单的方法)

您似乎要用一个新的、不是间谍的
ItemServiceImplementation
替换Mockito为您创建的
ItemServiceImplementation
。您应该删除
setUpMock()的第二行
。您是否考虑过使用H2作为真正的内存中数据库,而不是模拟数据库操作的复杂模拟?您准备testdata而不是模拟,并且可以使用普通的黑盒服务调用测试,而不是深入实现(从而防止任何简单的重构)。谢谢大家的建议。最后,在对mockito进行了几次尝试之后,我使用H2测试了我的项目(成功)。您似乎正在用一个新的不是间谍的
setUpMock()替换mockito为您创建的
ItemServiceImplementation
。您应该删除
setUpMock()的第二行
。您是否考虑过使用H2作为真正的内存中数据库,而不是模拟数据库操作的复杂模拟?您准备testdata而不是模拟,并且可以使用普通的黑盒服务调用测试,而不是深入实现(从而防止任何简单的重构)。谢谢大家的建议。最后,在与mockito进行了几次尝试后,我使用H2测试了我的项目(成功)。
@Service("itemService")
@Transactional
public class ItemServiceImplementation implements ItemCRUDService, ItemCostService, ItemFindService {



public static final Logger logger = LoggerFactory.getLogger(ItemServiceImplementation.class);

@Autowired
public void setItemRepository(ItemRepository itemRepository) {
    this.itemRepository = itemRepository;
}
@Autowired
public void setBasketRepository(BasketRepository basketRepository) {
    this.basketRepository = basketRepository;
}

private BasketRepository basketRepository;

private ItemRepository itemRepository;


public Iterable<Basket> showBasket() {

    return basketRepository.findAll();
}


public Iterable<Basket> addToBasket(String name, int qty) {

        if (basketRepository.exists(itemRepository.findOne(findItem(name).getId()).getId())==false) { 

        logger.info("add to empty list");
        basketRepository.save(new Basket(qty, itemCost(name, qty), findItem(name)));
        logger.info("adding");
    }

    modifyOrder(findItem(name).getId(), qty);
    itemCost(name, qty);
    logger.info("modify");

    return showBasket();

}
public Item findItem(String name) {

    for (Item item : itemRepository.findAll()) {
        if (item.getName().equals(name)) {
            return item;
        }
    }
    return null;
}
public int itemCost(String name, int qty) {

    int price = 0;

    int modulo = qty % findItem(name).getSpecialPrice();

    price = findItem(name).getPrice() * modulo
            + findItem(name).getSpecialPrice() * ((qty - modulo) / `findItem(name).getSpecialPrice());`

    return price;

}