Модульные тесты Как смоделировать репозиторий с помощью Mockito - PullRequest
0 голосов
/ 27 июня 2018

У меня проблема с заглушкой моего хранилища. Мне предложили просто создать еще одно application.properties (чего я не сделал) и использовать базу данных в памяти, такую ​​как H2. Мне было интересно, если я могу просто заглушить вызов, так что когда myDataService.findById (id) вызывается вместо того, чтобы пытаться получить это из базы данных, может быть возвращен только поддельный объект?

Я новичок в написании макетов для моих юнит-тестов и весенней загрузки в целом, так что, возможно, я что-то упустил. Код ниже (попытался упростить и сделал имена общими для размещения здесь).

Мой тестовый класс

public class MyServiceImplTest 
{
    private MyDataService myDataService;
    private NyService myService;
    private MyRepository myRepository;

    @Before
    public void setUp() {
        myDataService = Mockito.mock(MyDataServiceImpl.class);
        myService = new MyServiceImpl(myDataService);
    }

    @Test
    public void getById_ValidId() {
        doReturn(MyMockData.getMyObject()).when(myDataService).findById("1");
        when(myService.getById("1")).thenReturn(MyMockData.getMyObject());
        MyObject myObject = myService.getById("1");

        //Whatever asserts need to be done on the object myObject 
    }
}

Класс, используемый для вызова службы на уровне данных

@Service
public class MyServiceImpl implements MyService {
    MyDataService myDataService;

    @Autowired
    public MyServiceImpl(MyDataService myDataService) {
        this.myDataService = myDataService;
    }

    @Override
    public MyObject getById(String id) {
        if(id == null || id == "") {
            throw new InvalidRequestException("Invalid Identifier");
        }

        MyObject myObj;
        try {
            myObj = myDataService.findById(id);
        }catch(Exception ex) {
            throw new SystemException("Internal Server Error");
        }

        return myObj;
    }
}

Вот где у меня проблема в моем тесте. Когда вызывается метод findById (), хранилище переменных имеет значение null, поэтому при попытке сделать repository.findOne (id) он выдает исключение n. Это то, что я пытаюсь высмеять, но хранилище вызывает у меня проблемы.

@Repository
@Qualifier("MyRepo")
public class MyDataServiceImpl {

    @PersistenceContext
    private EntityManager em;

    private MyRepository repository;

    @Autowired
    public MyDataServiceImpl(MyRepository repository) {
        super(repository);
        this.repository = repository;
    }

    public MyObject findById(String id) {
        P persitentObject = repository.findOne(id);
        //Calls to map what persitentObject holds to MyObject and returns a MyObject 
    }
}

Код для MyRepository здесь только для того, чтобы показать, что это пустой интерфейс, расширяющий CrudRepository

public interface MyRepository extends CrudRepository<MyObjectPO, String>, JpaSpecificationExecutor<MyObjectPO> {

}

1 Ответ

0 голосов
/ 27 июня 2018

Позвольте мне начать с того, что вы на правильном пути, используя Constructor Injection, а не Field Injection (что делает написание тестов с макетами намного проще).

public class MyServiceImplTest 
{
    private MyDataService myDataService;
    private NyService myService;

    @Mock
    private MyRepository myRepository;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this); // this is needed for inititalizytion of mocks, if you use @Mock 
        myDataService = new MyDataServiceImpl(myRepository);
        myService = new MyServiceImpl(myDataService);
    }

    @Test
    public void getById_ValidId() {

        doReturn(someMockData).when(myRepository).findOne("1");
        MyObject myObject = myService.getById("1");

        //Whatever asserts need to be done on the object myObject 
    }
}

Звонок идет от вашего сервиса -> dataService. Но только ваши звонки из репозитория подвергаются насмешкам.
Таким образом, вы можете контролировать и тестировать все остальные части ваших классов (как service, так и dataService) и имитировать только вызовы репозитория.

...