Thuộc tính gốc với setters riêng cho các bài kiểm tra


10

Chúng tôi có đối tượng

public class MyObject{
    protected MyObject(){}

    public string Property1 {get;private set;}
    public string Property2 {get;private set;}
    public string Property3 {get;private set;}
    public string Property4 {get;private set;}
    public string Property5 {get;private set;}
    public string Property6 {get;private set;}
    public string Property7 {get;private set;}
    public string Property8 {get;private set;}
    public string Property9 {get;private set;}
    public string Property10 {get;private set;}
}

Trong mã sản xuất của chúng tôi, chúng tôi đưa đối tượng này thông qua automapper. Nó có thể truy cập các thuộc tính và đặt chúng chính xác.

Bây giờ khi chúng tôi muốn kiểm tra lớp này trong một đường ống trong tương lai, không thể đưa vào các thuộc tính bằng các giá trị giả (để được kiểm tra).

Có một vài lựa chọn có sẵn.

  • Các nhà xây dựng tùy chỉnh để chấp nhận các tham số cần thiết cho các thử nghiệm và đặt các thuộc tính, hiện tại cần 3 nhà xây dựng. Điều này không sạch vì các nhà xây dựng không phục vụ bất kỳ chức năng kinh doanh nào.

  • Làm cho các thuộc tính ảo để lớp có thể được khai thác. Nhưng việc đánh dấu các thuộc tính ảo không cung cấp bất kỳ giá trị kinh doanh nào và gây ô nhiễm cho lớp của tôi.

  • Thêm một trình xây dựng đối tượng vào lớp để xây dựng bên trong đối tượng. Một lần nữa không có giá trị kinh doanh gia tăng. Có lẽ sạch hơn một chút nhưng vẫn còn rất nhiều mã không liên quan trong các đối tượng miền.

Bất kỳ đề xuất, lời khuyên hoặc lựa chọn thay thế ở đây?

Câu trả lời:


8

Bạn có một số tùy chọn.

  • Đi trước và sử dụng các hàm tạo tùy chỉnh, thuộc tính ảo hoặc trình tạo đối tượng. Lý do đằng sau điều này là một vật thể nên tự đứng vững, và không phụ thuộc vào một số phép thuật như máy tự động. Một lớp học hoàn toàn vô dụng trừ khi có một số phép thuật đang diễn ra không phải là một lớp học được suy nghĩ rất tốt. "Giá trị doanh nghiệp" không phải là yếu tố quyết định duy nhất của một thiết kế tốt.

  • Bao gồm máy tự động trong quá trình thử nghiệm. Một số người sẽ nói đây không phải là một bài kiểm tra đơn vị nữa. Không quan trọng. Kiểm thử đơn vị không phải là loại thử nghiệm duy nhất .

  • Thực hiện một cái gì đó cung cấp chức năng của automapper đặc biệt để thử nghiệm. Bạn có thể dễ dàng viết một tiện ích nhỏ sẽ sử dụng sự phản chiếu để đưa đối tượng của bạn từ một từ điển chứa các giá trị và tên thuộc tính.

Ngoài ra, hãy xem câu hỏi và câu trả lời này: bạn muốn đặt nội dung riêng tư / công khai để kiểm tra hoặc sử dụng một số loại hack như PrivateObject?


3

Tôi không ngần ngại sử dụng sự phản chiếu cho những thứ như thế này trong các bài kiểm tra.

Tôi không thích làm cho mọi thứ trở nên ảo để chế giễu vì nó thay đổi mã vì lý do sai.

Tôi không biết automapper nhưng tôi đồng ý với @Mike rằng bao gồm nó trong các thử nghiệm có thể là một ý tưởng tốt. Các thử nghiệm đơn vị phân tích / kiểm tra tích hợp không phải là imo rất thú vị. Chắc chắn nếu bộ kiểm tra ngày càng lớn và chậm, bạn sẽ cần lọc và phân loại mọi thứ để chỉ chạy một tập hợp con hợp lý của tất cả các kiểm tra ở tần số cao nhất.

Hack mẫu bằng cách sử dụng sự phản chiếu, sử dụng nameof () sẽ có độ hoàn hảo tốt hơn nhưng sau đó bạn mất các loại:

public static class TestExtensions
{
    public static void SetProperty<TSource, TProperty>(
        this TSource source,
        Expression<Func<TSource, TProperty>> prop,
        TProperty value)
    {
        var propertyInfo = (PropertyInfo)((MemberExpression)prop.Body).Member;
        propertyInfo.SetValue(source, value);
    }
}

0

Đối với mục đích thử nghiệm đơn vị, hãy sử dụng các khung mô phỏng như Microsoft Fakes, TypeMock và JustMock để hỗ trợ cho việc chế nhạo các thành viên tư nhân.

Vui lòng xem qua Smocks (các gói @nuget có sẵn). Giới hạn của Smocks là, nó sẽ không cung cấp quyền truy cập cho các thành viên tư nhân. Nhưng nó có khả năng giả định các thành viên tĩnh và không ảo. Ngoài ra nó có sẵn miễn phí.

Một cách đơn giản nhất là sử dụng, PrivateObject / PrivateType.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.