2011-09-26 20 views
7

Tôi đang cố viết một bài kiểm tra đơn vị triển khai kho lưu trữ. Kho lưu trữ sử dụng RavenDB làm cơ sở dữ liệu. Đối với các bài kiểm tra đơn vị, tôi muốn giả lập các phần RavenDB. Để tạo ra các mocks (giả) tôi đang sử dụng FakeItEasy. Tôi đã tìm ra sẽ không có vấn đề gì với việc giả mạo/giả mạo kể từ khi API RavenDB được truy cập thông qua các giao diện.Giả mạo/mô phỏng giao diện cho lỗi "không có hàm tạo mặc định", làm cách nào có thể?

Tuy nhiên, tôi gặp sự cố khi cố gắng tạo mô hình cụ thể. Các bộ phận có liên quan của mã kiểm tra đơn vị của tôi trông như thế này:

[Fact] 
public void Test() { 
    UserDocument doc = ...; 
    IQueryable<UserDocument> where = A.Fake<IQueryable<UserDocument>>(); 
    A.CallTo(() => where.First()).Returns(doc); 
    IRavenQueryable<UserDocument> query = A.Fake<IRavenQueryable<UserDocument>>(); 
    IDocumentSession session = A.Fake<IDocumentSession>(); 
    A.CallTo(() => session.Query<UserDocument>()).Returns(query); 
    IDocumentStore store = A.Fake<IDocumentStore>(); 
    A.CallTo(() => store.OpenSession()).Returns(session); 
    . 
    . 
    . 
} 

Khi instantiating giả IRavenQueryable tôi nhận được một ngoại lệ. Đây là nhật ký từ nhân vật Xunit.net:

UnitTest.Test : FakeItEasy.Core.FakeCreationException : 
    Failed to create fake of type "System.Linq.IQueryable`1[UserDocument]". 

    Below is a list of reasons for failure per attempted constructor: 
    No constructor arguments failed: 
     No default constructor was found on the type System.Linq.IQueryable`1[UserDocument]. 


Stack Trace: 
    vid FakeItEasy.Core.DefaultExceptionThrower.ThrowFailedToGenerateProxyWithResolvedConstructors(Type typeOfFake, String reasonForFailureOfUnspecifiedConstructor, IEnumerable`1 resolvedConstructors) 
    vid FakeItEasy.Creation.FakeObjectCreator.TryCreateFakeWithDummyArgumentsForConstructor(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, String failReasonForDefaultConstructor, Boolean throwOnFailure) 
    vid FakeItEasy.Creation.FakeObjectCreator.CreateFake(Type typeOfFake, FakeOptions fakeOptions, IDummyValueCreationSession session, Boolean throwOnFailure) 
    vid FakeItEasy.Creation.DefaultFakeAndDummyManager.CreateFake(Type typeOfFake, FakeOptions options) 
    vid FakeItEasy.Creation.DefaultFakeCreatorFacade.CreateFake[T](Action`1 options) 

"Không tìm thấy hàm tạo mặc định" không có ý nghĩa vì những gì tôi đang cố gắng giả là giao diện. Có ai có một gợi ý những gì vấn đề có thể được?

+0

Tôi vừa nhận thấy rằng thông báo ngoại lệ của bạn đề cập đến ** "System.Linq.IQueryable \' 1 [UserDocument] "**, không cụ thể là" IRavenQueryable '. Bạn có chắc chắn ngoại lệ không xảy ra khi bạn khởi tạo 'IQueryable '? – Rob

+0

Vâng, tôi chắc chắn. Tuy nhiên, IRavenQueryable mở rộng giao diện IQueryable vì vậy tôi đoán FakeItEasy không thành công khi cố gắng giả mạo phần IQueryable nếu IRavenQueryable ... hoặc một cái gì đó tương tự. –

+0

Loại công khai của UserDocument có phải là công khai không? –

Trả lời

6

Bạn chính xác trong đó thông báo ngoại lệ không có ý nghĩa gì, đây là lỗi. Nó sẽ là tuyệt vời nếu bạn có thể cung cấp một giải pháp VS sao chép các lỗi và tập tin một vấn đề ở đây: https://github.com/patrik-hagne/FakeItEasy/

Lỗi là trong đó thông báo ngoại lệ sai được sử dụng, tuy nhiên phải có một cái gì đó sai mà làm cho việc tạo giả đi sai. Loại công cụ "UserDocument" có được công khai không? Nếu nó là nội bộ và bạn đã cấp quyền truy cập dự án thử nghiệm của mình cho nó thông qua việc sử dụng InternalsVisibleToAttribute, bạn cũng phải cấp cho thư viện tạo proxy truy cập vào nó: https://github.com/FakeItEasy/FakeItEasy/wiki/How-to-fake-internal-(Friend-in-VB)-types.

2

Giao diện IRavenQueryable<T>where T : new()type constraint không?

Nếu có, và UserDocument không cung cấp một ctor tham số ít hơn, điều này có thể gây ra vấn đề của bạn.

+0

Theo như tôi có thể nói, không có ràng buộc như vậy trên IRavenQueryable . Ngay cả khi có, UserDocument có một constructor parameterless. –

2

Tôi chỉ gặp phải vấn đề này, nhưng vấn đề của tôi không phải là xung quanh loại nội bộ. Vấn đề của tôi là với hội đồng có chứa loại không nằm trong thư mục bin của dự án thử nghiệm đơn vị.

Dường như FakeItEasy ném lỗi này khi nó không thể giải quyết một loại mà nó cần phải giả mạo. (Điều này làm cho tinh thần tại sao một loại nội bộ trong một hội đồng khác sẽ gây ra cùng một lỗi.)

Vì vậy, tôi đã có Project Foo, được tham chiếu bởi Project Bar. Project Bar có một giao diện công khai tham chiếu một kiểu công khai từ Project Foo. Project Bar.Tests có một tham chiếu đến Project Bar, nhưng không có Project Foo. Khi tôi xây dựng Bar.Tests, Bar.dll được đưa vào thư mục bin nhưng Foo.dll thì không. Khi FakeItEasy cố gắng giả mạo giao diện của tôi, nó không thể giải quyết loại mà nằm trong Foo.dll.

Thêm một tham chiếu đến dự án Foo trong dự án Bar.Tests tôi đảm bảo rằng Foo.dll làm theo cách của mình hơn và có cho FakeItEasy và làm cho lỗi này biến mất.

Vậy ...

Trong trường hợp của bạn, nó có thể là lắp ráp RavenDB của bạn (mà tôi giả sử chứa UserDocument) chỉ được tham chiếu bởi dự án thực tế của bạn và không bị sao chép vào đơn vị thử nghiệm xây dựng đầu ra của bạn.

+0

Tôi sẽ cố gắng tái tạo điều này và khắc phục sớm nhất có thể. –

1

Tôi biết đó là một bài đăng cũ, nhưng tôi đã gặp phải vấn đề tương tự. Điều tôi thấy là vấn đề là một kiểu trả về của một trong những phương thức được khai báo trong giao diện mà tôi đang cố giả mạo. Phương thức này đã trả về một đối tượng của một lớp nhất định, và lớp này không có một hàm tạo mặc định mà FakeItEasy có thể làm việc. Nếu ai đó bị lỗi này, hãy thử kiểm tra các đối tượng mà giao diện của bạn đang quay trở lại và nếu các lớp tương ứng có các hàm tạo mặc định.

+0

Bạn sẽ giải quyết vấn đề này như thế nào? Có thể giả mạo phương thức trả về một đối tượng không có hàm tạo mặc định không? –