当前位置: 首页 > 知识库问答 >
问题:

如何使用Mockito模拟列表方法

殷学
2023-03-14

我有一个调用Repository方法并返回列表的服务类。现在我想嘲笑它。我的单元测试场景如下:

  • 向模拟存储库添加一些模拟对象
  • 返回模拟对象列表的查询服务类
  • 断言列表大小

我的存储库类:

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface FoodRepository extends CrudRepository<Food, Long> {

    @Query(value = "SELECT * FROM FOOD WHERE FRESH = 1", nativeQuery = true)
    public List<Food> getMostFreshestFoods();
}

我的服务等级:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class FoodService {

    @Autowired
    private FoodRepository foodRepository;

    public List<Food> getMostFreshestFoods() {
        return foodRepository.getMostFreshestFoods();
    }
}

我的对象类:

public class Food {

    private Long id;

    private String foodName;

    private boolean fresh;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFoodName() {
        return foodName;
    }

    public void setFoodName(String foodName) {
        this.foodName = foodName;
    }

    public boolean isFresh() {
        return fresh;
    }

    public void setFresh(boolean fresh) {
        this.fresh = fresh;
    }
}

和我的测试课程:

import myapp.Food;
import myapp.FoodRepository;
import myapp.FoodService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class FoodTest {

    @Mock
    private FoodRepository foodRepository;

    @InjectMocks
    private FoodService foodService;

    @Captor
    private ArgumentCaptor<Food> foodArgumentCaptor;

    @Test
    public void testFreshestFoods() {

        Food food = new Food();
        food.setFoodName("Meat");
        food.setFresh(true);
        foodRepository.save(food);
        verify(foodRepository).save(foodArgumentCaptor.capture());
        assertThat(foodArgumentCaptor.getValue().getId(), is(notNullValue()));

        // Above I added mock data to database to query list from Service class method,
        // but I do not know how to do it. Using return always gives error

        // I want to do the following: Query the list from FoodService class and it should
        // return size 1 (the fake object (added above) )

    }


}

但是由于我是Mockito的新手,这对我来说有点困难。我想知道如何从FoodService类中获取列表,并且它应该返回在测试类中制作的假对象。

共有1个答案

曹建明
2023-03-14

我相信你正在寻找的是以下内容。使用Mockito进行测试不需要执行正常的工作流。另一种说法是,您不向DB添加内容,然后期望将其恢复。Mockito不知道数据库。它接管一个类(模拟类),并返回您告诉它的内容,或抛出异常,或什么都不做。这样做的目的是隔离被测试的类。因此,在您的情况下,假设数据在存储库中,然后模拟返回它。希望这是有意义的。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.List;

import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class FoodTest {

    @Mock
    private FoodRepository foodRepository;

    @InjectMocks
    private FoodService foodService;

    @Captor
    private ArgumentCaptor<Food> foodArgumentCaptor;

    @Test
    public void testFreshestFoods() {

        Food food = new Food();
        food.setFoodName("Meat");
        food.setFresh(true);

        // not needed
        //foodRepository.save(food);
        //verify(foodRepository).save(foodArgumentCaptor.capture());
        //assertThat(foodArgumentCaptor.getValue().getId(), is(notNullValue()));

        when(foodRepository.getMostFreshestFoods()).thenReturn(asList(food));

        List<Food> actual = foodService.getMostFreshestFoods();

        assertEquals(food, actual.get(0));
        verify(foodRepository).getMostFreshestFoods();
    }
}
 类似资料:
  • 我的测试存根是 我在这里做错了什么?

  • 问题内容: 如何用void返回类型模拟方法? 我实现了一个观察者模式,但是我无法用Mockito对其进行模拟,因为我不知道如何做。 我试图在互联网上找到一个例子,但没有成功。 我的课看起来像这样: 系统不会通过模拟触发。 我想显示上述系统状态。并根据他们做出断言。 问题答案: 看看Mockito API文档。由于链接的文档提到(点#12),你可以使用任何的家人从框架的的方法来嘲笑无效的方法。 例如

  • 我正试图模拟一个泛型方法,但无论我做什么尝试,都会得到类转换异常。正在测试的类是 而测试类是 其他帮助器类和接口有: 此外,出现此错误的原因可能是:1。您使用final/private/equals()/hashCode()方法中的任一个作为存根。这些方法不能被截取/验证。不支持在非公共父类上声明的模拟方法。2.内部when()不是对mock而是对其他对象调用method。

  • 使用mockito模拟一个方法会确保永远不会调用被模拟的方法吗?我有一个主类,它包含一些我想为其编写单元测试的代码,还有一个单元测试类MainTest,它包含主类的单元测试。 eg: 源类: JUnit测试(使用mockito) 这项测试失败了。为什么?

  • 我想通过ts-Mockito@2.5.0创建一个类的模拟对象,但我无法正确设置它。 以下是设计的测试用例: 正如测试用例所暗示的,我希望从我的模拟中返回“I AM mocked”的值。 我应该如何设置模拟,使其按预期工作? 旁白:这个测试用例只是为了展示我正在经历的奇怪行为。这不是我真正的测试。我想在不同服务的单元测试中使用模拟。)

  • 问题内容: 我有以下代码: 我想使用Mockito创建一个测试。我编写了如下测试: 我在网上收到NullPointerException: ,它表示“策略”列表已初始化,但为空。Mohito有什么办法可以像Spring一样浪费时间?是否将所有实现接口“策略”的实例自动添加到列表中? 顺便说一句,我在Wrapper类中没有任何二传手,如果可能的话,我想以这种方式离开。 问题答案: Mockito不知