最小起订量设置未返回正确值

问题描述

我已经查看了其他答案,但还没有找到任何有帮助的内容。也许我误解了。 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);
}

解决方法

所以看起来你创建了一个被测对象的模拟

//...

var mockClass = new Mock<DeleteDocument>(mongoClientMock.Object) { //<-- mocked instance
    CallBase = true 
};

//...

然后在进行测试时继续使用被测对象的另一个单独实例

//...

var ex = Assert.ThrowsException<ValidationException>(() => 
    new DeleteDocument(mongoClientMock.Object) //<-- new instance here
    .ProcessRequest(new DeleteDocumentRequest(null)
    {
        Ids = new[] { "6074d4da433ab6b5a731b82c" }
    }));

//...

由于您还想覆盖 GetDocumentCount 的行为,因此在进行测试时需要使用这种边缘情况下的模拟

[TestMethod]
public void DeleteDocument_DocumentCountDoesNotMatch_ReturnsErrorCode() {
    //Arrange

    //...omitted for brevity

    var mockClass = new Mock<DeleteDocument>(mongoClientMock.Object) {
        CallBase = true 
    };
    mockClass
        .Setup(x => x.GetDocumentCount(It.IsAny<IMongoCollection<Document>>(),It.IsAny<ObjectId[]>()))
        .Returns(Convert.ToInt64(99)); //<-- this need to not match request

    var request = new DeleteDocumentRequest(null) {
            Ids = new[] { "6074d4da433ab6b5a731b82c" }
    }

    //Act & 
    Action act = () => mockClass.Object.ProcessRequest(request);        

    //Assert
    ValidationException ex = Assert.ThrowsException<ValidationException>(act);
    Assert.AreEqual(-6,ex.Code);
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...