Làm cách nào để tôi tiêm các đối tượng thử nghiệm khi các đối tượng thực được tạo động?


8

Tôi muốn làm cho một lớp có thể kiểm tra bằng cách sử dụng tiêm phụ thuộc. Nhưng lớp tạo ra nhiều đối tượng trong thời gian chạy và truyền các giá trị khác nhau cho hàm tạo của chúng. Đây là một ví dụ đơn giản:

public abstract class Validator {
    private ErrorList errors;

    public abstract void validate();

    public void addError(String text) {
        errors.add(
            new ValidationError(text));
    }

    public int getNumErrors() {
        return errors.count()
    }
}

public class AgeValidator extends Validator {
    public void validate() {
        addError("first name invalid");
        addError("last name invalid");
    }
}

(Có nhiều lớp con khác của Trình xác thực.)

Cách tốt nhất để thay đổi điều này là gì, vì vậy tôi có thể tiêm một đối tượng giả thay vì Xác thựcError?

Tôi có thể tạo một AbstractValidationErrorFactory và thay thế nhà máy. Điều này sẽ hoạt động, nhưng có vẻ như cuối cùng tôi sẽ tạo ra hàng tấn nhà máy nhỏ và giao diện nhà máy, cho mọi sự phụ thuộc của loại này. Có cách nào tốt hơn?


Bạn đang cố gắng kiểm tra cái gì? Trình xác thực tạo Xác thựcErrors? Xác nhận giả mạoError sẽ không giúp đỡ. Khi mã đứng, Trình xác thực không hữu ích lắm vì bạn có thể gọi xác thực, nhưng bạn không thể nhận được các lỗi được tạo.
Michael Brown

Tôi đã bỏ nó, nhưng có các phương thức khác cung cấp quyền truy cập vào đối tượng ErrorList. Vì vậy, tôi có thể kiểm tra bằng cách sử dụng những người.
JW01

Câu trả lời:


4

Thay đổi đơn giản nhất để làm cho đơn vị lớp của bạn có thể kiểm tra được là

  1. (trích xuất mã tạo thành một phương thức (ảo) mới - bạn đã có cái này)
  2. phân lớp lớp đã kiểm tra, ghi đè phương thức tạo để tạo đối tượng giả phù hợp thay vì lớp thực
  3. viết bài kiểm tra đơn vị của bạn :-)

Tất nhiên, điều này không tốt lắm. Nhưng nó cho phép bạn bao quát lớp bằng các bài kiểm tra đơn vị, sau đó bạn có thể bắt đầu tái cấu trúc theo hướng thiết kế lý tưởng, mà không sợ phá vỡ mã với những thay đổi sâu hơn.

Tham chiếu bắt buộc: Làm việc hiệu quả với Bộ luật kế thừa .

Về thiết kế lý tưởng đó thật khó để nói nhiều, vì ví dụ của bạn thiếu chi tiết và bối cảnh. Nếu bạn cho chúng tôi biết thêm về những gì bạn đang nhắm đến để kiểm tra và vai trò của lớp được kiểm tra là gì, chúng tôi có thể có thể giúp đỡ nhiều hơn.


Đó là cách tiếp cận chung của tôi, nhưng trong trường hợp này, có một số lớp con của Trình xác thực và có rất nhiều thiết lập liên quan đến thử nghiệm. Nếu tôi tạo một lớp con thử nghiệm, thì tôi cũng phải tạo một lớp con thử nghiệm cho mọi lớp con thực sự của Trình xác thực. Vì vậy, tôi sẽ kết thúc việc sao chép rất nhiều công việc thiết lập của mình. Nhưng có lẽ điều đó là cần thiết trong trường hợp này.
JW01

2

Thông thường giải pháp cho vấn đề này là mẫu Nhà cung cấp:

public class Validator {
    public Provider<ValidationError> errorProvider;

    public void addError(String text) {
        errors.add(errorProvider.get(text));
    }
}

Nhà cung cấp là một cái gì đó tương tự như nhà máy. Trong trường hợp này, nó sẽ trở lại mới ValidationErrormỗi lần getđược gọi.

Thông tin chi tiết có thể được tìm thấy trong cuốn sách Dependency Injection trong phần 3.3.2 (Từ chối với mẫu Nhà cung cấp).

Guice , cho exampe, có Nhà cung cấp cho việc này. Nếu bạn muốn một cái gì đó tinh vi hơn, bạn có thể sử dụng CertifiedInject .

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.