我的应用和mongo数据库之间有一个服务层。
我正在尝试使用moq构建单元测试 我对moq很新,所以我从我认为是一个微不足道的测试开始。
要测试的代码:
public List<BsonDocument> GetAllSettings()
{
var collection = MongoDatabase.GetCollection<BsonDocument>("Settings");
var query = from e in collection.AsQueryable()
select e;
var settings = query.ToList();
return settings;
}
其中: 设置是一个集合 MongoDatabase是MongoDBDriver.MongoDatabase
我试过这个作为我的测试:
[Test()]
public void GetAllSettingsTest()
{
//Arrange
BsonDocument doc01 = new BsonDocument();
BsonDocument doc02 = new BsonDocument();
var mongoDatabase = new Mock<MongoDatabase>();
var collection = new Mock<MongoCollection<BsonDocument>>();
mongoDatabase.Setup(f => f.GetCollection(MongoCollection.Settings)).Returns(collection.Object);
collection.Object.Insert(doc01);
collection.Object.Insert(doc02);
ILogger logger = new Logger();
DatabaseClient.DatabaseClient target = new DatabaseClient.DatabaseClient(logger);
target.MongoDatabase = mongoDatabase.Object;
MongoCursor<BsonDocument> cursor = collection.Object.FindAllAs<BsonDocument>();
List<BsonDocument> expected = cursor.ToList();
List<BsonDocument> actual;
//Act
actual = target.GetAllSettings();
//Assert
Assert.AreEqual(expected, actual);
}
我收到了“无法找到无参数构造函数”的错误:
mongoDatabase.Setup(f =&gt; f.GetCollection(MongoCollections.Settings))。返回(collection.Object);
错误是指MongoCollection对象。我认为它没有构造函数。
我可以做些什么来让我的测试运行?
答案 0 :(得分:7)
这个问题很可能与:How do I mock MongoDB objects to test my data models?
有关无论如何,这里是模拟
所需的最小Moq配置 var message = string.Empty;
var serverSettings = new MongoServerSettings()
{
GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard,
ReadEncoding = new UTF8Encoding(),
ReadPreference = new ReadPreference(),
WriteConcern = new WriteConcern(),
WriteEncoding = new UTF8Encoding()
};
var server = new Mock<MongoServer>(serverSettings);
server.Setup(s => s.Settings).Returns(serverSettings);
server.Setup(s => s.IsDatabaseNameValid(It.IsAny<string>(), out message)).Returns(true);
var databaseSettings = new MongoDatabaseSettings()
{
GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard,
ReadEncoding = new UTF8Encoding(),
ReadPreference = new ReadPreference(),
WriteConcern = new WriteConcern(),
WriteEncoding = new UTF8Encoding()
};
var database = new Mock<MongoDatabase>(server.Object, "test", databaseSettings);
database.Setup(db => db.Settings).Returns(databaseSettings);
database.Setup(db => db.IsCollectionNameValid(It.IsAny<string>(), out message)).Returns(true);
var mockedCollection = collection.Object;
无论如何,正如我在链接问题中所提到的,当MongoDriver的任何内部工作发生变化时,这可能没有用。
答案 1 :(得分:4)
我不熟悉MongoDbDriver.MongoDatabase,但如果它像我认为的那样工作,那么你就不能直接嘲笑它。您需要抽象MongoDB访问代码,并模拟它。这将是一个实际的单元测试。 e.g。
public interface IMongoDBRepository
{
Collection<T> GetCollection<T>(string name) where T BsonDocument;
}
public class MongoDbRepository : IMongoDBRepository
{
public Collection<T> GetCollection<T>(string name)
where T : BsonDocument
{
return MongoDatabase.GetCollection<BsonDocument>(name);
}
}
现在,在你的代码中,你注入一个IMongoDBRepository(使用你喜欢的任何DI方法),你的代码看起来像这样:
private IMongoDBRepository _mongoDBRepository; //this gets injected
public List<BsonDocument> GetAllSettings()
{
var collection = _mongoDBRepository.GetCollection<BsonDocument>("Settings");
var query = from e in collection.AsQueryable()
select e;
var settings = query.ToList();
return settings;
}
最后你的单元测试:
[Test()]
public void GetAllSettingsTest()
{
//Arrange
BsonDocument doc01 = new BsonDocument();
BsonDocument doc02 = new BsonDocument();
var mongoDatabase = new Mock<IMongoDBRepository>();
var collection = new Mock<MongoCollection<BsonDocument>>();
mongoDatabase.Setup(f => f.GetCollection(MongoCollection.Settings)).Returns(collection.Object);
collection.Object.Insert(doc01);
collection.Object.Insert(doc02);
//rest of test
}