监视或模拟Java中的RESTFul类时的NullPointer

时间:2019-05-17 12:38:59

标签: java rest testing compiler-errors mocking

我正在尝试对名为AdRestService的Rest服务类进行单元测试。

package api.rest;

// import things..

@ApplicationScoped
@Path("/ad")
@Default // To be injected in the Test
public class AdRestService {

    @Inject
    private AdService adService;
    @Inject
    private AdProducer adProducer;

    @POST
    @Consumes("application/json")
    public Response create(Ad ad) {
        Long newId = null;
        try {
            newId = adService.create(ad);
        } catch(IllegalArgumentException i) {
            return Response.status(Status.BAD_REQUEST).build();
        } catch(Exception e) {
            return Response.status(Status.BAD_GATEWAY).build();
        }

        adProducer.send(ad, "adsCreate");   
        return Response.status(Status.CREATED).location(URI.create("/ad/" + newId.toString())).build();
    }

    @GET
    @Produces("application/json")
    public List<Ad> getAll() {
        return adService.getAll();

    }
}

测试类是:

package api.rest;

//import things ..


@ExtendWith(JpaUnit.class)
@ExtendWith(MockitoExtension.class)
public class AdRestServiceTest {

    @Spy
    @PersistenceContext(unitName = "AdPUTest")
    EntityManager em;

    @Mock // @InjectMocks // @Spy ??
    private AdRestService adRestService;

    @Mock // @InjectMocks // @Spy ??
    private AdServiceImpl adServiceImpl;

    @Test
    public void testGetAll() {
        int size = initDataStore();
        assertEquals(size, adRestService.getAll().size());
    }

    @Test
    public void testGet() {
        initDataStore();
        List<Ad> ads = adRestService.getAll(); // ads is null and so we cannot test isEmpty
        //if (ads.isEmpty())
        //  initDataStore();
        Long id = ads.get(0).getId();
        Ad ad = adRestService.get(id);

        assertEquals(ads.get(0).getId(), ad.getId());
        assertEquals(ads.get(0).getTitle(), ad.getTitle());
    }



    ///// Methods for testing
    private List<Ad> getAds() {

        List<Ad> ads = new ArrayList<>();
        long numberOfAd = Math.round((Math.random() * 10)) + 1;
        for (int i = 0; i < numberOfAd; i++) {
            ads.add(getRandomAd());
        }
        return ads;
    }

    private int initDataStore() {
        int size = adRestService.getAll().size();
        List<Ad> ads = getAds();    
        for (Ad ad : ads) {
            adServiceImpl.create(ad);
        }
        return size + ads.size();
    }

    private Ad getRandomAd() {
        Ad ad = new Ad();
        ad.setTitle(UUID.randomUUID().toString());
        ad.setDescription(UUID.randomUUID().toString());

        Random r = new Random();
        ad.setPrice(r.nextDouble());

        Long randomDate = -946771200000L + (Math.abs(r.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000));
        ad.setDate(new Date(randomDate));

        ad.setUserId(r.nextLong());
        ad.setCategoryId(r.nextLong());

        return ad;
    }
    /////



}

如果我放置@InjectMocks,则在尝试调用adRestService.getAll();时会收到NullPointerException。我尝试使用@Spy真正创建对象,因此避免使用NullPointer,但出现相同的错误。

这里有两个有效的类:

@ExtendWith(JpaUnit.class)
@ExtendWith(MockitoExtension.class)
public class AdServiceTest {

    @Spy
    @PersistenceContext(unitName = "AdPUTest")
    EntityManager em;

    @InjectMocks
    private AdServiceImpl adServiceImpl;

    @Test
    public void testGetAll() {
        int size = initDataStore();
        assertEquals(size, adServiceImpl.getAll().size());
    }

测试:

package domain.service;

import java.util.List;

import domain.model.Ad;

public interface AdService {

    public Long create(Ad ad);

    public void delete(Ad ad);

    public void update(Ad ad);

    public List<Ad> getAll();

    public Ad get(Long adId);
}

我不知道为什么它不能用于其余服务,但是可以正确地用于AdService。任何帮助吗?

0 个答案:

没有答案