描述
我正在測驗 mobgoDB 資料庫中的批量插入,在@BeforeEach我實體化資料庫的方法中,@AfterEach我洗掉了在今天的拼圖集合中創建的所有檔案。
但是最后一個總是失敗,有隨機結果,有時測驗通過有時它顯示這個367或366或364或364。
我補充說@RepeatedTest(4)以確保它不會變化。
代碼 :
班級考試
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import com.github.mathieusoysal.codingame_stats.CodinGame;
import com.github.mathieusoysal.codingame_stats.puzzle.Puzzle;
import org.bson.Document;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import io.github.mathieusoysal.util.MongoDBMockTest;
public class PuzzleDaoTest extends MongoDBMockTest {
private PuzzlesDao puzzleDao;
@BeforeEach
public void setUp() throws Exception {
super.setUp();
puzzleDao = new PuzzlesDao(mongoClient, "CodinGame-stats");
}
@AfterEach
public void tearDown() throws Exception {
mongoClient.getDatabase("CodinGame-stats")
.getCollection(PuzzlesDao.PUZZLES_HISTORY_COLLECTION)
.deleteMany(new Document());
super.tearDown();
}
@Test
void testSaveAll_shouldReturnTrue_withTwoPuzzles() {
List<Puzzle> puzzles = new CodinGame().getPuzzles().subList(0, 2);
assertTrue(puzzleDao.saveAll(puzzles));
}
@Test
void testSaveAll_shouldAugmentCollectionSize_withTwoPuzzles() {
List<Puzzle> puzzles = new CodinGame().getPuzzles().subList(0, 2);
puzzleDao.saveAll(puzzles);
assertEquals(puzzles.size(), countDocuments());
}
@RepeatedTest(4)
void testSaveAll_shouldAugmentCollectionSize_withAllPuzzles() {
List<Puzzle> puzzles = new CodinGame().getPuzzles();
puzzleDao.saveAll(puzzles);
assertEquals(puzzles.size(), countDocuments());
}
private long countDocuments() {
return mongoClient.getDatabase("CodinGame-stats")
.getCollection(PuzzlesDao.PUZZLES_HISTORY_COLLECTION)
.countDocuments();
}
}
克隆專案
為了輕松復制它,您可以在dev分支
但是這個結果是隨機的,有時測驗通過有時會顯示錯誤。
任何人有任何想法來解決這個問題?
uj5u.com熱心網友回復:
您遇到的問題不是測驗問題,而是實施問題。看著:
class PuzzlesDao...
public boolean saveAll(List<Puzzle> puzzles) {
List<WriteModel<Document>> bulkWrites = new ArrayList<>();
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
puzzles.parallelStream()
.forEach(puzzle -> bulkWrites.add(new InsertOneModel<>(Document.parse(gson.toJson(puzzle)))));
BulkWriteOptions bulkWriteOptions = new BulkWriteOptions().ordered(false);
BulkWriteResult bulkWriteResult = collection.bulkWrite(bulkWrites, bulkWriteOptions);
return bulkWriteResult.wasAcknowledged();
}
您正在使用parallelStream()沒有像collect(..)或這樣的關閉操作count()。當批量操作已經運行時,forEach 代碼仍在執行。因此,由此產生的行為是不可預測的。一種啟發式方法是永遠不要在forEach(). 如果你必須那么使用一個簡單的 for 回圈在我看來是更好的選擇。
我建議進行以下更改:
public boolean saveAll(List<Puzzle> puzzles) {
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
List<WriteModel<Document>> bulkWrites =
puzzles.parallelStream()
.map(puzzle -> new InsertOneModel<>(Document.parse(gson.toJson(puzzle))))
.collect(Collectors.toList());
BulkWriteOptions bulkWriteOptions = new BulkWriteOptions().ordered(false);
BulkWriteResult bulkWriteResult = collection.bulkWrite(bulkWrites, bulkWriteOptions);
return bulkWriteResult.wasAcknowledged();
}
我個人幾乎從不使用,parallelStream()除非我能證明它以一種有價值的方式提高了性能,而它通常不會。使用只是stream()擺脫了并行性的復雜性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/406795.html
標籤:
