Không tiêm phụ thuộc có đẩy gánh nặng thử nghiệm xuống chuỗi?


9

Tôi đang tìm hiểu về tiêm phụ thuộc và trong khi tôi có thể thấy sự hấp dẫn của nó khi viết thư viện chức năng, tôi không thấy cách nó giải quyết bất cứ điều gì khi bạn cũng sẽ là người sử dụng các thư viện.

Nó làm cho việc kiểm tra thư viện đơn giản hơn nhiều, vì không có nhiều thứ để kiểm tra.

Nhưng cuối cùng bạn sẽ phải kiểm tra chức năng được tiêm của mình khi bạn sử dụng thư viện và phải đối phó với các chức năng chế giễu và khai thác từ thư viện chuẩn.

Đây là một trường hợp cụ thể mà tôi đang xử lý trong Node.js :

function compile(options) {
  var files = options.files;
  var texCompiler = options.texCompiler;
  var pdfMerger = options.pdfMerger;

  return Promise.all(files.map(texCompiler(files)))
    .then(pdfMerger);
}

Đó là chuyện nhỏ để kiểm tra: tiêm các đối tượng giả hoặc gián điệp làm texCompilerpdfMergerlà một miếng bánh vì chức năng thực sự không làm được gì nhiều. Tất cả những gì tôi có thể kiểm tra là cả hai chức năng được gọi theo đúng trình tự.

Mặc dù vậy, nó không cứu tôi khỏi việc kiểm tra chức năng texCompilerpdfMergerchức năng của tôi . Họ trông giống như thế:

var tex2Pdf = Promise.method(function tex2Pdf(tex_doc) {
    var latex_command = 'pdflatex';
    var pdf_output_filename = path.parse(tex_doc).name + '.pdf';
    var cmd = latex_command + ' ' + tex_doc;
    var options = {
      cwd: path.resolve(tex_doc, '..') // pdflatex will only look for custom
      // cls files in the cwd and includes relative to the cwd
    };
    child_process.spawn(cmd, options)
      .on('end', function() {
        console.log('tex2Pdf finish');
        debugger;
        return path.resolve(tex_doc, '..', pdf_output_filename);
      })
      .on('error', function(e) {
        throw e;
      });
});


var mergeTwoPdf = Promise.method(function mergeTwoPdf(pdf_files) {
  var output_file = randomId() + '.pdf';
  var cmd = 'gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=' + output_file + ' ' + pdf_files[0] + ' ' + pdf_file[1];
  child_process.spawn(cmd)
    .on('finish', function() {
      return output_file;
    })
  .on('error', function(e) {
    throw (e);
  });
});

Đây là điều có thật, và nó là một nỗi đau lớn hơn để kiểm tra. Tôi phải chế giễu child_process.spawnmột điệp viên để đảm bảo rằng nó được gọi với các đối số phù hợp, nhưng nó thực sự không làm gì cả, vì tôi không thực sự muốn hợp nhất bất kỳ tệp PDF nào khi chạy thử nghiệm và các giả của tôi phải phát ra đúng sự kiện để chức năng không bị kẹt.

Đây là những vấn đề tôi sẽ gặp phải nếu tôi không tiêm phụ thuộc vào đoạn mã đầu tiên của mình và sử dụng các chức năng này thay thế. Và nó thực sự có cảm giác như tôi đang đẩy vấn đề đi xa hơn mà không giải quyết nó.

Tôi có hiểu nhầm tiêm phụ thuộc? Tôi đang làm sai à?

Câu trả lời:


8

Có vẻ như bạn đang thiếu điểm kiểm tra.

Đó là chuyện nhỏ để kiểm tra: tiêm giả hoặc gián điệp như texCompiler và pdfMerger là một miếng bánh vì chức năng thực sự không làm được gì nhiều. Tất cả những gì tôi có thể kiểm tra là cả hai chức năng được gọi theo đúng trình tự.

Tuyệt vời! Nếu chức năng đang làm công việc tầm thường, thì kiểm tra nên tầm thường. Tương tự, nếu tất cả chức năng đó thực sự đang gọi A thì B, thì bạn không xác thực nhiều mã của mình.

Toàn bộ điểm của các bài kiểm tra tốt là cô lập những gì bạn đang kiểm tra, vì vậy khi kiểm tra thất bại, bạn có thể biết rõ hơn những gì đã sai. Phụ thuộc tiêm giúp điều đó.

Và nó thực sự có cảm giác như tôi đang đẩy vấn đề đi xa hơn mà không giải quyết nó.

Chắc chắn, trong trường hợp này bạn không "giải quyết nó" bởi vì mã của bạn có các phụ thuộc khó chịu rất khó để cô lập. Bạn cần phải làm việc với hệ thống tập tin. Bạn cần gọi các quá trình bên ngoài này. Đôi khi đó là bản chất của con thú.

Dependency Injection không loại bỏ sự phụ thuộc, nó chỉ lật chúng xung quanh để bạn có thể chọn chúng là gì. Điều đó giúp cô lập mã để thử nghiệm. Nó giúp mã linh hoạt hơn khi những phụ thuộc đó chắc chắn thay đổi. Nhưng nó không giết được chúng - mã của bạn vẫn cần có thể thực hiện tất cả những điều tương tự ở đâu đó .


Điều đó có ý nghĩa. Có điều gì khác tôi có thể làm để làm cho việc kiểm tra những phụ thuộc khó chịu đó dễ dàng hơn không?
tải vào

2
@springloaded - Chủ nghĩa thực dụng. Cách ly phụ thuộc là tốt, nhưng trong một ứng dụng như thế này, nó không có ý nghĩa nhiều. Kiểm tra tích hợp kém hơn kiểm tra đơn vị (mất nhiều thời gian hơn, dễ vỡ hơn, khó ràng buộc hơn với nguyên nhân) nhưng nếu kiểm tra đơn vị sẽ không cung cấp cho bạn nhiều, chúng có thể không có giá trị thời gian.
Telastyn

2

Tôi nghĩ rằng đó là thử nghiệm mà bạn đang hiểu lầm nếu có bất cứ điều gì.

Tôi sẽ kiểm tra việc tạo tệp PDF của bạn bằng cách tạo tệp PDF và so sánh nó với tệp tốt đã biết.

Tôi sẽ kiểm tra hợp nhất tệp PDF của bạn bằng cách hợp nhất hai tệp PDF và so sánh đầu ra với, một lần nữa, một tệp tốt đã biết.


2
Vì vậy, bạn đang nói rằng tôi nên làm các bài kiểm tra tích hợp trên mã này nhưng không có bài kiểm tra đơn vị nào? Trong bối cảnh đó, tiêm phụ thuộc thậm chí có ý nghĩa?
tải vào

3
@springloaded: Bạn tạo một điểm hợp lệ. Tôi chỉ nói rằng, chỉ vì DI không có ý nghĩa trong kịch bản cụ thể của bạn, không nhất thiết có nghĩa là nó thất bại trong tất cả các kịch bản. Đối phó với các thư viện bên ngoài chủ yếu là một câu chuyện tích hợp; quan điểm của DI là làm cho sự tích hợp đó trở nên rõ ràng hơn là nướng nó trực tiếp vào mã của bạn.
Robert Harvey

@RobertHarvey Chắc chắn, tôi thấy DI có thể hữu ích như thế nào ngoài trường hợp sử dụng của tôi
tải vào

hmm Tôi muốn nói ts không phải là một bài kiểm tra tích hợp ở cấp độ đó. Nếu bạn thích, bạn có thể xuất dữ liệu thô và đưa bit ghi vào đĩa nếu bạn muốn nó "hợp nhất" hơn.
Ewan
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.