使用mockito和junit 5初始化java中的模拟服务

发布于 2025-01-09 18:39:42 字数 3312 浏览 1 评论 0原文

我正在尝试学习一些集成测试,同时创建一个项目来制作游戏数据库,并且有一个在其方法中调用服务的类,

    public DigitalGame findDigitalGameByTitleAndPlatform(DigitalGame digitalGame){
        if(digitalGame == null){
            return null;
        }
        return GamesJPAService.iDigitalGameRepository.findDigitalGameByTitleAndPlatform(digitalGame.getTitle(), digitalGame.getPlatform());
    }

如下所示,当项目作为 @Service 启动时,GamesJpaService 被初始化为 @Service应用。但无论是自动装配、新建还是我发现尝试初始化它的任何其他方法,都没有在测试类中初始化。例如,使用 @InjectMocks 注释

@Service
public class GamesJPAService implements IJpaServices {
    public static IDigitalGameRepository iDigitalGameRepository;

    @Autowired
    private IDigitalGameRepository iDigitalGameRepo;


    @PostConstruct
    public void init(){
        iDigitalGameRepository = this.iDigitalGameRepo;
    }
}

它调用的 IDigitalGameRepository 看起来像:

public interface IDigitalGameRepository extends JpaRepository<DigitalGame, String> {
    DigitalGame findDigitalGameByTitleAndPlatform(String title, Platform platform);
}

我从前面的代码中省略了一些方法。我的测试类也看起来像(目前)

@DisplayName("Digital Games Dao Test")
class DigitalGamesDaoTest {

    Set<Peripheral> compatiblePeriphs = new HashSet<>();
    Set<SupportedLanguages> supportedLanguages = new HashSet<>();
    List<Mods> mods = new ArrayList<>();
    List<DLC> dlc = new ArrayList<>();
    DigitalGame olliolli = new DigitalGame("olliolli", "", "sports", "olliolli", new ReleaseDate(), new Platform(), compatiblePeriphs, new Developer(), new Publisher(), new Region(), supportedLanguages, new NoneEnglish(), mods, dlc, "", new SpecialEdition(), true, new Platform());

    private IDigitalGamesDao digitalGamesDao;

    @Mock
    GamesJPAService gamesJpaService;


    @BeforeEach
    void setUp() {
        digitalGamesDao = new DigitalGamesDao();
    }

   @Test
    @DisplayName("insertDigitalGame should return false when digital game already in database")
    public void insertDigitalGameShouldReturnFalseWhenDigitalGameInDatabase(){
        EntityManager mockEntityManager = mock(EntityManager.class);

        when(GamesJPAService.iDigitalGameRepository.findDigitalGameByTitleAndPlatform(olliolli.getTitle(), olliolli.getPlatform())).thenReturn(olliolli);
        doReturn(olliolli).when(digitalGamesDao.findDigitalGameByTitleAndPlatform(olliolli));
        when(digitalGamesDao.findDigitalGameByTitleAndPlatform(olliolli)).thenReturn(olliolli);

        when(mockEntityManager.merge(olliolli)).thenReturn(null);
        assertFalse(digitalGamesDao.insertDigitalGame(olliolli));
    }

    @Test
    @DisplayName("insertDigitalGame should return true when digital game added to database")
    public void insertDigitalGameShouldReturnTrueWhenDigitalGameNotInDatabase(){

    }

,我收到一个空指针异常,

java.lang.NullPointerException: Cannot invoke "com.me.gamedatabasebackend.dao.gamesJPA.IDigitalGameRepository.findDigitalGameByTitleAndPlatform(String, com. me.gamedatabasebackend.model.platform.Platform)”因为“com.me.gamedatabasebackend.dao.gamesJPA.GamesJPAService.iDigitalGameRepository”为 null

由于 GamesJPAService 尚未经过测试,我需要知道如何跳过它并仅返回值。因此,我需要帮助找到一种方法,从我的测试类中进行组件扫描,或者以可用的方式将 GamesJPAService 导入其中。

I'm trying to learn some integration testing whilst creating a project to make a game database, and have got a class that calls a service within it's methods

    public DigitalGame findDigitalGameByTitleAndPlatform(DigitalGame digitalGame){
        if(digitalGame == null){
            return null;
        }
        return GamesJPAService.iDigitalGameRepository.findDigitalGameByTitleAndPlatform(digitalGame.getTitle(), digitalGame.getPlatform());
    }

The GamesJpaService as shown below, is initialised as an @Service when the project is started as an application. But is not initialised within the test class, no matter whether it is autowired,newed up, or any other method I have spotted to try and initialise it. for example using the @InjectMocks annotation

@Service
public class GamesJPAService implements IJpaServices {
    public static IDigitalGameRepository iDigitalGameRepository;

    @Autowired
    private IDigitalGameRepository iDigitalGameRepo;


    @PostConstruct
    public void init(){
        iDigitalGameRepository = this.iDigitalGameRepo;
    }
}

The IDigitalGameRepository that it calls looks like:

public interface IDigitalGameRepository extends JpaRepository<DigitalGame, String> {
    DigitalGame findDigitalGameByTitleAndPlatform(String title, Platform platform);
}

I have ommited some methods from the proceeding code. My test class also looks like (at the moment)

@DisplayName("Digital Games Dao Test")
class DigitalGamesDaoTest {

    Set<Peripheral> compatiblePeriphs = new HashSet<>();
    Set<SupportedLanguages> supportedLanguages = new HashSet<>();
    List<Mods> mods = new ArrayList<>();
    List<DLC> dlc = new ArrayList<>();
    DigitalGame olliolli = new DigitalGame("olliolli", "", "sports", "olliolli", new ReleaseDate(), new Platform(), compatiblePeriphs, new Developer(), new Publisher(), new Region(), supportedLanguages, new NoneEnglish(), mods, dlc, "", new SpecialEdition(), true, new Platform());

    private IDigitalGamesDao digitalGamesDao;

    @Mock
    GamesJPAService gamesJpaService;


    @BeforeEach
    void setUp() {
        digitalGamesDao = new DigitalGamesDao();
    }

   @Test
    @DisplayName("insertDigitalGame should return false when digital game already in database")
    public void insertDigitalGameShouldReturnFalseWhenDigitalGameInDatabase(){
        EntityManager mockEntityManager = mock(EntityManager.class);

        when(GamesJPAService.iDigitalGameRepository.findDigitalGameByTitleAndPlatform(olliolli.getTitle(), olliolli.getPlatform())).thenReturn(olliolli);
        doReturn(olliolli).when(digitalGamesDao.findDigitalGameByTitleAndPlatform(olliolli));
        when(digitalGamesDao.findDigitalGameByTitleAndPlatform(olliolli)).thenReturn(olliolli);

        when(mockEntityManager.merge(olliolli)).thenReturn(null);
        assertFalse(digitalGamesDao.insertDigitalGame(olliolli));
    }

    @Test
    @DisplayName("insertDigitalGame should return true when digital game added to database")
    public void insertDigitalGameShouldReturnTrueWhenDigitalGameNotInDatabase(){

    }

and I am getting a null pointer exception,

java.lang.NullPointerException: Cannot invoke "com.me.gamedatabasebackend.dao.gamesJPA.IDigitalGameRepository.findDigitalGameByTitleAndPlatform(String, com.me.gamedatabasebackend.model.platform.Platform)" because "com.me.gamedatabasebackend.dao.gamesJPA.GamesJPAService.iDigitalGameRepository" is null

As GamesJPAService is not being tested I need to know how to skip it and just return the value. So I need help to find a way for either, doing a component scan from my test class, or importing the GamesJPAService into it in a useable manner.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倒数 2025-01-16 18:39:42

您需要用一些类似的想法来注释您的测试类以使注入工作

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { SpringTestConfiguration.class })
DisplayName("Digital Games Dao Test")
class DigitalGamesDaoTest {
...

但是您有一个空指针,因为 GamesJPAService.iDigitalGameRepository 为空。这是一个静态属性,并且 GamesJPAService 的实例是一个模拟,因此永远不会调用 init() 方法。

You need to annotate your test class with some think like that to make injection works

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { SpringTestConfiguration.class })
DisplayName("Digital Games Dao Test")
class DigitalGamesDaoTest {
...

But you have a nullpointer because GamesJPAService.iDigitalGameRepository is null. That's a static property and the instance of GamesJPAService is a mock so the init() method is never call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文