Mockito:verify(mock)问题

6

我正在努力解决这个问题,但是遇到了很大的困难,请问有人能帮帮我吗?

显然我做错了一些根本性的事情,我已经尝试验证每一个Mock对象,但似乎没有起作用。

 org.mockito.exceptions.misusing.UnfinishedVerificationException: 
 Missing method call for verify(mock) here:
 -> at     com.muuves.reservosity.service.TestProductServiceImpl.search_OneHourSlot_TwoBookingAvailable(TestProductServiceImpl.java:86)

 Example of correct verification:
verify(mock).doSomething()

Also, this error might show up because you verify either of: final/private/equals()  /hashCode() methods.
Those methods *cannot* be stubbed/verified.

at com.muuves.reservosity.service.TestProductServiceImpl.setUp(TestProductServiceImpl.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

这是我的测试

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class TestProductServiceImpl {    
    ProductServiceImpl instance;
    @Mock
    EntityManager em;
    @Mock
    CriteriaBuilder builder;
    @Mock 
    CriteriaQuery<Product_Details> c;
    @Mock
    Root<Product_Details> productRoot;
    @Mock
    TypedQuery<Product_Details> typedQuery;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this); 
        instance = new  ProductServiceImpl();
        instance.setEm(em);
        instance.setCriteriaBuilder(builder);
        instance.setQuery(c);
        instance.setProductRoot(productRoot);
        instance.setTypedQuery(typedQuery);
    }

    @Test
    public void search_OneHourSlot_NoBookingAvailable() {
        List<Product_Details> products = booking(60);
        when(em.getCriteriaBuilder()).thenReturn(builder);
        when(builder.createQuery(Product_Details.class)).thenReturn(c);
        when(c.from(Product_Details.class)).thenReturn(productRoot);
        when(em.createQuery(c)).thenReturn(typedQuery);
        when(typedQuery.getResultList()).thenReturn(products);
        Search search = new Search();
        search.setDate("2013-02-09");
        search.setLocation("Cork");
        search.setPrice("20");
        search.setTime("14:00-15:00");
        search.setType("Football");
        List<Search_Result> result = instance.search(search);
        Assert.assertEquals(0, result.size());
    }
    @Test
    public void search_OneHourSlot_TwoBookingAvailable() {
        List<Product_Details> products = booking(60);
        when(em.getCriteriaBuilder()).thenReturn(builder);
        when(builder.createQuery(Product_Details.class)).thenReturn(c);
        when(c.from(Product_Details.class)).thenReturn(productRoot);
        when(em.createQuery(c)).thenReturn(typedQuery);
        when(typedQuery.getResultList()).thenReturn(products);
        Search search = new Search();
        search.setDate("2013-02-09");
        search.setLocation("Cork");
        search.setPrice("20");
        search.setTime("14:00-17:00");
        search.setType("Football");
        List<Search_Result> result = instance.search(search);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals("2013-02-09 15:00", result.get(0).getTime());
        Assert.assertEquals("Google", result.get(0).getProductDetails().getProduct_Name());
    }

    @Test
    public void search_OneHourSlot_EndTimeAfterClosing() {
        List<Product_Details> products = booking(60);
        when(em.getCriteriaBuilder()).thenReturn(builder);
        when(builder.createQuery(Product_Details.class)).thenReturn(c);
        when(c.from(Product_Details.class)).thenReturn(productRoot);
        when(em.createQuery(c)).thenReturn(typedQuery);
        when(typedQuery.getResultList()).thenReturn(products);
        Search search = new Search();
        search.setDate("2013-02-09");
        search.setLocation("Cork");
        search.setPrice("20");
        search.setTime("14:00-20:00");
        search.setType("Football");
        List<Search_Result> result = instance.search(search);
        Assert.assertEquals(1, result.size());
        Assert.assertEquals("2013-02-09 15:00", result.get(0).getTime());
        Assert.assertEquals("Google", result.get(0).getProductDetails().getProduct_Name());
        verify(em);
    }

    @Test
    public void search__StartTimeBeforeOpening() {
        List<Product_Details> products = booking(60);
        when(em.getCriteriaBuilder()).thenReturn(builder);
        when(builder.createQuery(Product_Details.class)).thenReturn(c);
        when(c.from(Product_Details.class)).thenReturn(productRoot);
        when(em.createQuery(c)).thenReturn(typedQuery);
        when(typedQuery.getResultList()).thenReturn(products);
        Search search = new Search();
        search.setDate("2013-02-09");
        search.setLocation("Cork");
        search.setPrice("20");
        search.setTime("08:00-13:00");
        search.setType("Football");
        List<Search_Result> result = instance.search(search);
        Assert.assertEquals(3, result.size());
        Assert.assertEquals("2013-02-09 09:00", result.get(0).getTime());
        Assert.assertEquals("Google", result.get(0).getProductDetails().getProduct_Name());
        Assert.assertEquals("2013-02-09 10:00", result.get(1).getTime());
        Assert.assertEquals("Google", result.get(1).getProductDetails().getProduct_Name());
        Assert.assertEquals("2013-02-09 11:00", result.get(2).getTime());
        Assert.assertEquals("Google", result.get(2).getProductDetails().getProduct_Name());
    }
    @Test
    public void search__StartTimeAndEndTimeBeforeOpening() {
        List<Product_Details> products = booking(60);
        when(em.getCriteriaBuilder()).thenReturn(builder);
        when(builder.createQuery(Product_Details.class)).thenReturn(c);
        when(c.from(Product_Details.class)).thenReturn(productRoot);
        when(em.createQuery(c)).thenReturn(typedQuery);
        when(typedQuery.getResultList()).thenReturn(products);
        Search search = new Search();
        search.setDate("2013-02-09");
        search.setLocation("Cork");
        search.setPrice("20");
        search.setTime("06:00-09:00");
        search.setType("Football");
        List<Search_Result> result = instance.search(search);
        Assert.assertEquals(0, result.size());
    }
    @Test
    public void search__StartTimeAndEndTimeAfterClosing() {
        List<Product_Details> products = booking(60);
        when(em.getCriteriaBuilder()).thenReturn(builder);
        when(builder.createQuery(Product_Details.class)).thenReturn(c);
        when(c.from(Product_Details.class)).thenReturn(productRoot);
        when(em.createQuery(c)).thenReturn(typedQuery);
        when(typedQuery.getResultList()).thenReturn(products);
        Search search = new Search();
        search.setDate("2013-02-09");
        search.setLocation("Cork");
        search.setPrice("20");
        search.setTime("17:00-21:00");
        search.setType("Football");
        List<Search_Result> result = instance.search(search);
        Assert.assertEquals(0, result.size());
    }
    @Test
    public void search__StartTimeAndEndTimeExactlyOpeningClosing() {
        List<Product_Details> products = booking(60);
        when(em.getCriteriaBuilder()).thenReturn(builder);
        when(builder.createQuery(Product_Details.class)).thenReturn(c);
        when(c.from(Product_Details.class)).thenReturn(productRoot);
        when(em.createQuery(c)).thenReturn(typedQuery);
        when(typedQuery.getResultList()).thenReturn(products);
        Search search = new Search();
        search.setDate("2013-02-09");
        search.setLocation("Cork");
        search.setPrice("20");
        search.setTime("09:00-17:00");
        search.setType("Football");
        List<Search_Result> result = instance.search(search);
        Assert.assertEquals(5, result.size());
        Assert.assertEquals("2013-02-09 09:00", result.get(0).getTime());
        Assert.assertEquals("Google", result.get(0).getProductDetails().getProduct_Name());
        Assert.assertEquals("2013-02-09 10:00", result.get(1).getTime());
        Assert.assertEquals("Google", result.get(1).getProductDetails().getProduct_Name());
        Assert.assertEquals("2013-02-09 11:00", result.get(2).getTime());
        Assert.assertEquals("Google", result.get(2).getProductDetails().getProduct_Name());
        Assert.assertEquals("2013-02-09 13:00", result.get(3).getTime());
        Assert.assertEquals("Google", result.get(3).getProductDetails().getProduct_Name());
        Assert.assertEquals("2013-02-09 15:00", result.get(4).getTime());
        Assert.assertEquals("Google", result.get(4).getProductDetails().getProduct_Name());
    }
    private List<Product_Details> booking(int slot){
        List<Product_Details> products = new ArrayList<Product_Details>();
        Product_Details product = new Product_Details();
        product.setProduct_Name("Google");
        product.setSaturday_Open("09:00-17:00");
        product.setDates_Closed("2013-12-25");
        product.setTime_Per_Slot(slot);
        List<Booking_Details> bookings = new ArrayList<Booking_Details>();
        Booking_Details booking1 = new Booking_Details();
        booking1.setBooked_Date("2013-02-09 12:00");
        bookings.add(booking1);
        Booking_Details booking2 = new Booking_Details();
        booking2.setBooked_Date("2013-02-09 14:00");
        bookings.add(booking2);
        Booking_Details booking3 = new Booking_Details();
        booking3.setBooked_Date("2013-02-09 16:00");
        bookings.add(booking3);
        product.setBookings(bookings);
        products.add(product);
        return products;
    }
}

如果有人可以帮助我,那将会很棒。

我已经使用您类的空实现进行了测试,一切都运行良好(即没有此类异常,显然测试未通过其断言)。也许您可以尝试同样的方法:注释掉所有实现并检查是否可以解决这个问题。然后再开始添加代码,并尝试确定是什么导致了此异常的出现。如果还不清楚,请回到我们这里,或者如果您能解决它,请自己发布答案。 - bowmore
3个回答

5

您试图以错误的方式使用Mockito框架的验证方法。它用于验证某些行为发生了一次。

在您的测试中,您应该指定已发生的行为(指方法调用)。

这里是一个检查发送邮件方法的测试示例:

@RunWith(MockitoJUnitRunner.class)
public class MailSenderTest {

    @Mock
    private JavaMailSender javaMailSender;

    @InjectMocks
    private MailSenderImpl mailSender;

    @Test
    public void testSendMail() {

        String from = "somemail@gmail.com";
        String to = "Danothermail@gmail.com";
        String title = "Test";
        String text = "Hello world!";

        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(title);
        message.setText(text);

        mailSender.sendMail(to, title, text);

        Mockito.verify(javaMailSender).send(message);
    }

}

如您所见,在verify(..)之后,我指定了要检查的方法调用。换句话说,在示例的最后一行中,我检查在执行我的服务方法send(..)的sendMail(...)方法期间,JavaMailSender的send(..)方法已使用正确的参数进行调用。

请查看Mockito官方页面。那里有很多简单且有用的示例,并带有良好的描述。这是一个链接。


0

将此添加到每个测试中,它可以工作了,谢谢 harpun,你真的帮了我一个大忙

    verify(em).createQuery(c);
    verify(builder).createQuery(Product_Details.class);
    verify(c).from(Product_Details.class);
    verify(em).createQuery(c);
    verify(typedQuery).getResultList();

0

错误信息表明,在受影响的测试方法search_OneHourSlot_TwoBookingAvailable()中,您缺少了一个verify(em)...;调用。

我强烈建议重新格式化您的测试代码,将每个测试方法中的断言与测试代码分开。


我已经在每个方法中添加了verify(em),但似乎并没有解决问题。 - user1408682
1
@user1408682 调用 verify(em) 是不够的。你必须验证完整的方法调用,比如 verify(em).method(a)。请参考 Mockito API 第四章。 - harpun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接