【问题标题】:How to test a method that calls different methods inside?如何测试内部调用不同方法的方法?
【发布时间】:2014-11-11 13:16:29
【问题描述】:

我在服务类中有一个名为addSong(song,userId) 的单元测试方法。我从Dao class 调用其中的三个方法。我正在使用 Easy mock 来模拟 dao class。在设置中,我首先模拟我在addSong(song,userId) 中调用的所有方法,然后调用service.addsong(song,userId) 方法测试。

但我收到以下错误:

Java.lang.IllegalStateException: missing behavior definition for the preceding method call:
MusicPlayerDao.addSong(song)
Usage is: expect(a.foo()).andXXX()
    at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:42)
    at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:94)
    at org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:97)
    at service.MusicPlayerDao$$EnhancerByCGLIB$$45bc3ca1.addSong(<generated>)
    at service.MusicPlayerServiceImpl.addSong(MusicPlayerServiceImpl.java:43)
    at AddSongTest.addSongs(AddSongTest.java:90)

这是我的代码:

private void addSongSetup() throws SQLException{
    this.album = new Album();
    album.setAlbumName("album");
    this.genre = new Genre();
    genre.setGenreName("genre");
    this.song = new Song("song",this.album,3,"artist","composer",this.genre);
    EasyMock.expect(this.dao.addSong(song)).andReturn(1).anyTimes();
    EasyMock.expect(this.dao.addGenre(genre, 1)).andReturn(1).anyTimes();
    EasyMock.expect(this.dao.addAlbum(album, 1)).andReturn(1).anyTimes();
    EasyMock.expect(this.dao.userIdSongsMapping(1,1)).andReturn(1).anyTimes();
}

@Test
public void addSongs(){

    this.album = new Album();
    album.setAlbumName("album");
    this.genre = new Genre();
    genre.setGenreName("genre");
    this.song = new Song("song",this.album,3,"artist","composer",this.genre);
    try {
        System.out.println(this.dao.addSong(song));
        boolean status = this.service.addSong(song, 1);
        assertEquals(true,status);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

我在服务类中的 addSong 方法:

public boolean addSong(Song song, int userId) throws Exception {

    MusicPlayerDaoInterface musicPlayerDao = MusicPlayerDao.getInstance();
    boolean status = false;
    int songId = 0;

    TransactionManager transactionManager = TransactionManagerImpl
            .getInstance();
    try {
        if (song != null) {
            if (song.getTitle() != null) {
                transactionManager.begin();
                songId = musicPlayerDao.addSong(song);
                song.setSongId(songId);
                if (song.getGenre() != null
                        && song.getGenre().getGenreName() != null) {
                    musicPlayerDao.addGenre(song.getGenre(),
                            song.getSongId());
                }
                if (song.getAlbum() != null
                        && song.getAlbum().getAlbumName() != null) {
                    musicPlayerDao.addAlbum(song.getAlbum(),
                            song.getSongId());
                }
                if (userId != 0 && songId != 0) {
                    musicPlayerDao.userIdSongsMapping(userId,
                            song.getSongId());
                }
                transactionManager.commit();
                status = true;
            }
        }
    } catch (SQLException | RollbackException | HeuristicMixedException
            | HeuristicRollbackException e) {
        transactionManager.rollback();
        status = false;
        throw e;

    }

    return status;
}

我不知道我错了。请帮忙。

【问题讨论】:

  • 能否请您添加 Song(Gener 和 Album)的实现?你在这些类中实现了equals和hashcode吗?

标签: java unit-testing junit easymock


【解决方案1】:

我认为您在记录预期行为后缺少EasyMock.replay 语句。类似的东西

EasyMock.replay(this.dao);

来自EasyMock guide

要获得一个模拟对象,我们需要

  1. 为我们要模拟的界面创建一个 Mock 对象
  2. 记录预期行为
  3. 将 Mock 对象切换到重放状态

【讨论】:

    【解决方案2】:

    尝试从addSongs 测试用例中删除以下行:

    this.album = new Album();
    album.setAlbumName("album");
    this.genre = new Genre();
    genre.setGenreName("genre");
    this.song = new Song("song",this.album,3,"artist","composer",this.genre);
    

    我假设 addSongSetup 在 addSongs 之前被调用(例如,@Before)。您正在为 addSong 中的变量专辑、流派和歌曲重新分配值,我想,EasyMock 无法与 addSongSetup 中的模拟设置匹配(取决于 EasyMock 是如何实现的)

    1. 您忘记在歌曲、专辑、流派或中实现 hashcode 或 equals,
    2. EasyMock 使用对象标识(即参考比较)

    我猜是 1。

    【讨论】:

      猜你喜欢
      • 2016-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多