2012-11-06 31 views
7

Tôi có một lớp dịch vụ giữa ứng dụng của tôi và cơ sở dữ liệu mongo.Làm cách nào để sử dụng moq để kiểm tra lớp dịch vụ MongoDB?

Tôi đang cố gắng xây dựng một bài kiểm tra đơn vị sử dụng moq Tôi khá mới để moq vì vậy tôi bắt đầu với những gì tôi nghĩ sẽ là một thử nghiệm tầm thường.

Mã để kiểm tra:

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; 
    } 

đâu: Cài đặt là một Bộ sưu tập MongoDatabase là một MongoDBDriver.MongoDatabase

tôi đã cố gắng này là thử nghiệm của tôi:

[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); 
    } 

tôi đang gặp lỗi "Không thể tìm thấy hàm tạo tham số" tại:

mongoDatabase.Setup (f => f.GetCollection (MongoCollections.Settings)). Returns (collection.Object);

Lỗi đề cập đến đối tượng MongoCollection. Tôi không nghĩ rằng nó có một nhà xây dựng.

Tôi có thể làm gì để chạy thử nghiệm?

+0

Donot mock, 'var collection = new Mock >();' và thử –

+1

Tôi xin lỗi, tôi không hiểu những gì bạn đang đề xuất. – Richard210363

Trả lời

3

Tôi không quen với MongoDbDriver.MongoDatabase, nhưng nếu nó hoạt động như tôi nghĩ, thì bạn không thể giả lập nó trực tiếp. Bạn cần phải trừu tượng mã truy cập MongoDB và giả sử điều đó. Đó sẽ là một thử nghiệm đơn vị thực tế. ví dụ.

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); 
    } 
} 

Bây giờ, trong mã của bạn, bạn tiêm một IMongoDBRepository (sử dụng bất cứ phương pháp nào bạn thích DI) và mã của bạn sẽ trông giống như sau:

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; 
} 

Và cuối cùng kiểm tra đơn vị của bạn:

[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 
} 
+0

Điều này đã cho tôi một số nội dung cần xem xét nhưng sẽ không hoạt động. Bạn không thể tiêm một đối tượng IMongoDBRepository vào phương thức. Mã phải sử dụng một MongoDatabase không phải là một IMongoDBRepository vì nó phải đọc một cơ sở dữ liệu thực khi chạy. – Richard210363

+0

Ngoài ra, MongoDatabase.GetCollection (tên); không thể được thực hiện như GetCollection không phải là một phương pháp tĩnh. Tôi sẽ sử dụng ý tưởng cơ bản và xem liệu tôi có thể làm cho nó hoạt động không. – Richard210363

7

câu hỏi này có thể liên quan nhất đến: How do I mock MongoDB objects to test my data models?

Dù sao, cô ấy e là cấu hình Moq tối thiểu cần thiết để mô phỏng

 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; 

Dù sao, như tôi đã đề cập trong câu hỏi được liên kết, điều này có thể không hữu ích khi bất kỳ hoạt động bên trong của MongoDriver thay đổi.

+0

Mã cho 'bộ sưu tập' ở đâu? – zsong

+2

Dường như bị thiếu ... 'var collection = new Mock > (database.Object," COLLECTIONNAME ", collectionSettings);' và một số collectionSettings thích hợp. –

+0

Bạn có thể vui lòng giải thích về ý nghĩa của bạn bằng cách làm việc bên trong của MongoDB Driver thay đổi? Bạn có nghĩa là các thay đổi đối với Trình điều khiển API C# MongoDB khi bạn nâng cấp lên phiên bản mới hơn của Trình điều khiển C# MongoDB? –

Các vấn đề liên quan