### Question:
AsyncThread extends Thread implements IEpochTrainer { @Override public void run() { RunContext context = new RunContext(); Nd4j.getAffinityManager().unsafeSetDevice(deviceNum); log.info("ThreadNum-" + threadNumber + " Started!"); while (!getAsyncGlobal().isTrainingComplete()) { if (episodeComplete) { startEpisode(context); } if(!startEpoch(context)) { break; } episodeComplete = handleTraining(context); if(!finishEpoch(context)) { break; } if(episodeComplete) { finishEpisode(context); } } } AsyncThread(MDP<OBSERVATION, ACTION, ACTION_SPACE> mdp, TrainingListenerList listeners, int threadNumber, int deviceNum); MDP<OBSERVATION, ACTION, ACTION_SPACE> getMdp(); void setHistoryProcessor(IHistoryProcessor.Configuration conf); void setHistoryProcessor(IHistoryProcessor historyProcessor); @Override void run(); void incrementSteps();  }### Answer:
@Test public void when_episodeComplete_expect_neuralNetworkReset() { mockTrainingContext(100, 10, 10); mockTrainingListeners(); thread.run(); verify(mockNeuralNet, times(10)).reset(); assertEquals(10, thread.getEpochCount()); assertEquals(10, thread.getEpisodeCount()); assertEquals(100, thread.getStepCount()); }
@Test public void when_notifyNewEpochReturnsStop_expect_threadStopped() { mockTrainingContext(); mockTrainingListeners(true, false); thread.run(); assertEquals(0, thread.getEpochCount()); assertEquals(1, thread.getEpisodeCount()); assertEquals(0, thread.getStepCount()); }
@Test public void when_notifyEpochTrainingResultReturnsStop_expect_threadStopped() { mockTrainingContext(); mockTrainingListeners(false, true); thread.run(); assertEquals(1, thread.getEpochCount()); assertEquals(1, thread.getEpisodeCount()); assertEquals(10, thread.getStepCount()); }
@Test public void when_run_expect_trainSubEpochCalledAndResultPassedToListeners() { mockTrainingContext(100, 10, 5); mockTrainingListeners(false, false); thread.run(); assertEquals(20, thread.getEpochCount()); assertEquals(10, thread.getEpisodeCount()); assertEquals(100, thread.getStepCount()); verify(mockTrainingListeners, times(20)).notifyEpochTrainingResult(eq(thread), any(IDataManager.StatEntry.class)); }