【发布时间】:2021-06-25 20:25:40
【问题描述】:
我查看了其他答案,但尚未找到任何帮助。也许我是误会了。 GetDocumentCount 模拟不起作用。
被测类:
public class DeleteDocument
{
private readonly IMongoClient _mongoClient;
public DeleteDocument(IMongoClient mongoClient)
{
this._mongoClient = mongoClient;
}
public override bool ProcessRequest(DeleteDocumentRequest request)
{
var docObjectIds = request.Ids.Select(ObjectId.Parse).ToArray();
var documents = _mongoClient.GetDocumentsCollection(Constants.DATABASE);
var documentCount = GetDocumentCount(documents, docObjectIds);
if (documentCount != request.Ids.Length)
{
throw new ValidationException(-6, "The document count doesn't match");
}
... more code here
return true;
}
public virtual long GetDocumentCount(IMongoCollection<Document> docs, ObjectId[] objIds)
{
return docs.Find(x => objIds.Contains(x.Id)).CountDocuments();
}
}
单元测试是遗留代码并且无法正常工作,我很难理解它是否真的正确地模拟了 MongoDb。我还没有找到很多很好的 MongoDb 模拟示例。这是完整的单元测试:
[TestMethod]
public void DeleteDocument_DocumentCountDoesNotMatch_ReturnsErrorCode()
{
var mockIMongoCollection = new Mock<IMongoCollection<Document>>();
var asyncCursor = new Mock<IAsyncCursor<Document>>();
var docCollection = new[]
{
// this is the document to delete
new Document
{
CreateDate = DateTime.UtcNow,
Id = new ObjectId("6074d4da433ab6b5a731b82c"),
IsActive = true
}
};
mockIMongoCollection.Setup(collection => collection.FindSync(
Builders<Document>.Filter.Empty,
It.IsAny<FindOptions<Document>>(),
default))
.Returns(asyncCursor.Object);
asyncCursor.SetupSequence(async => async.MoveNext(default))
.Returns(true)
.Returns(false);
asyncCursor.SetupGet(async => async.Current)
.Returns(docCollection);
var mongoDatabaseMock = new Mock<IMongoDatabase>();
mongoDatabaseMock.Setup(x => x.GetCollection<Document>(
It.IsAny<string>(),
It.IsAny<MongoCollectionSettings>()))
.Returns(mockIMongoCollection.Object);
var mongoClientMock = new Mock<IMongoClient>();
mongoClientMock.Setup(x => x.GetDatabase(
It.IsAny<string>(),
It.IsAny<MongoDatabaseSettings>()))
.Returns(mongoDatabaseMock.Object);
var mockClass = new Mock<DeleteDocument>(mongoClientMock.Object)
{ CallBase = true };
mockClass.Setup(
x => x.GetDocumentCount
(It.IsAny<IMongoCollection<Document>>(),
It.IsAny<ObjectId[]>()))
.Returns(Convert.ToInt64(1));
var ex = Assert.ThrowsException<ValidationException>(() =>
new DeleteDocument(mongoClientMock.Object)
.ProcessRequest(new DeleteDocumentRequest(null)
{
Ids = new[] { "6074d4da433ab6b5a731b82c" }
}));
Assert.AreEqual(-6, ex.Code);
}
【问题讨论】:
-
您使用模拟的方式也很重要。
-
如果你在测试
DeleteDocument,你想模拟IMongoClient,而不是DeleteDocument。 -
@sellotape 我已经更新了我的单元测试代码。我模拟了 IMongoClient,但不清楚 GetDocumentCount 是如何被覆盖的?
标签: c# unit-testing moq