JMock запускает AssertionError: вызов ожидается один раз, никогда не вызывался - но он был вызван - PullRequest
0 голосов
/ 13 декабря 2011

Я довольно новичок в программировании на Java, но я попытался начать с модульного тестирования и поэтому также использовал JMock. Я уже реализовал несколько тестовых случаев (с JMock), которые работают, но этот я просто не могу запустить.

Что я сделал: Я написал тестовый класс, который создает фиктивный объект, а затем я ожидаю один (используя oneOf) вызов. После запуска модульного теста он говорит, что он не работает (но в журналах говорится иначе, так как я распечатываю данные, которые я возвратил при вызове, используя will(returnValue(x)).

Следующая забавная / странная вещь - если я изменяю oneOf на «никогда», модульный тест завершается успешно, но он выдает исключение:

Exception in thread "Thread-2" java.lang.AssertionError: unexpected invocation: blockingQueue.take()

ожидания: ожидается никогда, никогда не вызывается: blockingQueue.take (); возвращается что случилось до этого: ничего!

Вот код:

@RunWith(JMock.class)
public class ExecuteGameRunnableTest {
    private Mockery context = new JUnit4Mockery();
    private Thread testObject;
    private BlockingQueue<Game> queueMock;
    private Executor executorMock;

    @SuppressWarnings("unchecked")
    @Before
    public void setUp() {
        queueMock = context.mock(BlockingQueue.class);
        executorMock = context.mock(Executor.class);
        testObject = new Thread(new ExecuteGameRunnable(queueMock, executorMock, true));
    }

    @After
    public void tearDown() {
        queueMock = null;
        executorMock = null;
        testObject = null;
    }

    @Test
    public void testQueueTake() throws InterruptedException {
        final Game game = new Game();
        game.setId(1);
        game.setProcessing(false);
        context.checking(new Expectations() {{
            never(queueMock).take(); will(returnValue(game));
        }});
        testObject.start();
        context.assertIsSatisfied();
    }
}

и исполняемый файл, который я тестирую:

public class ExecuteGameRunnable implements Runnable {
    private BlockingQueue<Game> queue;
    private Executor executor;
    private Boolean unitTesting = false;
    static Logger logger = Logger.getLogger(ExecuteGameRunnable.class);

    public ExecuteGameRunnable(BlockingQueue<Game> queue, Executor executor) {
        this.queue = queue;
        this.executor = executor;
    }

    public ExecuteGameRunnable (BlockingQueue<Game> queue, Executor executor, Boolean unitTesting) {
        this(queue,executor);
        this.unitTesting = unitTesting;
    }

    public void run() {
        try {
            do {
                if (Thread.interrupted()) throw new InterruptedException();
                Game game = queue.take();
                logger.info("Game "+game.getId()+" taken. Checking if it is processing"); // THIS ONE PRINTS OUT THE GAME ID THAT I RETURN WITH JMOCK-FRAMEWORK
                if (game.isProcessing()) {
                    continue;
                }
                game.updateProcessing(true);

                executor.execute(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub

                    }
                });
            } while (!unitTesting);
        } catch (InterruptedException ex) {
            logger.info("Game-Execution-Executor interrupted.");
            return;
        } catch (DataSourceException ex) {
            logger.fatal("Unable to connect to DB whilst executing game: "+id_game,ex);
            return;
        }
    }
}

1 Ответ

1 голос
/ 24 января 2012

JMock не безопасен для потоков.Он предназначен для поддержки модульного тестирования, а не очень маленького интеграционного теста.Честно говоря, в этом случае я бы использовал реальный BlockingQueue, а не фиктивный.И нет никакого способа, которым у вас должен быть флаг unitTesting в вашем производственном коде.

Еще одна вещь, вам не нужно устанавливать поля в тестовом классе на нуль, jUnit сбрасывает экземпляр для каждоготест.

...