Cách viết thử nghiệm đơn vị cho Angular / TypeScript cho các phương thức riêng tư với Jasmine


196

Làm thế nào để bạn kiểm tra một chức năng riêng tư trong góc 2?

class FooBar {

    private _status: number;

    constructor( private foo : Bar ) {
        this.initFooBar();

    }

    private initFooBar(){
        this.foo.bar( "data" );
        this._status = this.fooo.foo();
    }

    public get status(){
        return this._status;
    }

}

Giải pháp tôi tìm thấy

  1. Đặt mã kiểm tra vào bên trong bao đóng hoặc Thêm mã bên trong bao đóng lưu trữ các tham chiếu đến các biến cục bộ trên các đối tượng hiện có trong phạm vi bên ngoài.

    Sau đó loại bỏ mã kiểm tra bằng cách sử dụng một công cụ. http://philipwalton.com/articles/how-to-unit-test-private-fifts-in-javascript/

Xin đề nghị cho tôi một cách tốt hơn để giải quyết vấn đề này nếu bạn đã làm gì?

PS

  1. Hầu hết câu trả lời cho loại câu hỏi tương tự như câu hỏi này không đưa ra giải pháp cho vấn đề, đó là lý do tại sao tôi hỏi câu hỏi này

  2. Hầu hết các nhà phát triển nói rằng bạn KHÔNG kiểm tra các chức năng riêng tư nhưng tôi không nói rằng họ sai hoặc đúng, nhưng trường hợp của tôi cần phải kiểm tra riêng tư.


11
kiểm tra chỉ nên kiểm tra giao diện công cộng, không phải thực hiện riêng tư. Các bài kiểm tra bạn thực hiện trên giao diện công cộng cũng sẽ bao gồm cả phần riêng tư.
toskv

16
Tôi thích cách một nửa câu trả lời thực sự nên được bình luận. OP đặt câu hỏi, làm thế nào để bạn X? Câu trả lời được chấp nhận thực sự cho bạn biết cách thực hiện X. Sau đó, hầu hết những người còn lại quay lại và nói, không chỉ tôi sẽ không nói với bạn X (mà rõ ràng là có thể) mà bạn nên làm Y. Hầu hết các công cụ kiểm tra đơn vị (Tôi không nói về chỉ JavaScript ở đây) có khả năng kiểm tra các chức năng / phương thức riêng tư. Tôi sẽ tiếp tục giải thích lý do tại sao dường như bị lạc trong vùng đất JS (rõ ràng, đưa ra một nửa câu trả lời).
Đệ tứ

13
Đó là cách thực hành lập trình tốt để chia nhỏ vấn đề thành các tác vụ có thể quản lý, do đó, hàm "foo (x: type)" sẽ gọi các hàm riêng là a (x: type), b (x: type), c (y: Another_type) và d ( z: yet_another_type). Bây giờ bởi vì foo, đang quản lý các cuộc gọi và sắp xếp các thứ lại với nhau, nó tạo ra một loại nhiễu loạn, giống như mặt sau của các tảng đá trong một dòng, bóng tối thực sự khó để đảm bảo tất cả các phạm vi được kiểm tra. Vì vậy, dễ dàng hơn để đảm bảo rằng mỗi tập hợp phạm vi phụ là hợp lệ, nếu bạn cố kiểm tra "foo" cha mẹ, việc kiểm tra phạm vi sẽ trở nên rất phức tạp trong các trường hợp.
Đệ tứ

18
Điều này không có nghĩa là bạn không kiểm tra giao diện công cộng, rõ ràng là bạn làm, nhưng kiểm tra các phương thức riêng tư cho phép bạn kiểm tra một loạt các đoạn ngắn có thể quản lý được (cùng lý do bạn đã viết chúng ở nơi đầu tiên, tại sao bạn lại hoàn tác điều này khi nói đến thử nghiệm) và chỉ vì các thử nghiệm trên giao diện công cộng là hợp lệ (có thể chức năng gọi giới hạn phạm vi đầu vào) không có nghĩa là các phương thức riêng tư không bị lỗi khi bạn thêm logic nâng cao hơn và gọi chúng từ khác chức năng cha mẹ mới,
Đệ tứ

5
nếu bạn đã kiểm tra chúng đúng cách với TDD, bạn sẽ không cố gắng tìm ra cái quái gì bạn đang làm sau này, khi nào bạn nên kiểm tra chúng một cách chính xác.
Đệ tứ

Câu trả lời:


343

Tôi với bạn, mặc dù đó là một mục tiêu tốt để "chỉ kiểm tra đơn vị API công khai", có những lúc nó không đơn giản và bạn cảm thấy mình đang lựa chọn giữa việc thỏa hiệp API hoặc kiểm tra đơn vị. Bạn đã biết điều này rồi, vì đó chính xác là những gì bạn yêu cầu làm, vì vậy tôi sẽ không tham gia vào nó. :)

Trong TypeScript, tôi đã khám phá một vài cách bạn có thể truy cập các thành viên tư nhân để thử nghiệm đơn vị. Hãy xem xét lớp này:

class MyThing {

    private _name:string;
    private _count:number;

    constructor() {
        this.init("Test", 123);
    }

    private init(name:string, count:number){
        this._name = name;
        this._count = count;
    }

    public get name(){ return this._name; }

    public get count(){ return this._count; }

}

Mặc dù TS hạn chế quyền truy cập vào các thành viên lớp bằng cách sử dụng private, protectednhưng public, trình biên dịch JS không có thành viên riêng tư, vì đây không phải là điều trong JS. Nó hoàn toàn được sử dụng cho trình biên dịch TS. Do đó:

  1. Bạn có thể xác nhận anyvà thoát trình biên dịch khỏi cảnh báo bạn về các hạn chế truy cập:

    (thing as any)._name = "Unit Test";
    (thing as any)._count = 123;
    (thing as any).init("Unit Test", 123);

    Vấn đề với cách tiếp cận này là trình biên dịch đơn giản là không biết bạn đang làm gì đúng any, vì vậy bạn không nhận được lỗi loại mong muốn:

    (thing as any)._name = 123; // wrong, but no error
    (thing as any)._count = "Unit Test"; // wrong, but no error
    (thing as any).init(0, "123"); // wrong, but no error

    Điều này rõ ràng sẽ làm cho việc tái cấu trúc trở nên khó khăn hơn.

  2. Bạn có thể sử dụng truy cập mảng ( []) để nhận các thành viên riêng:

    thing["_name"] = "Unit Test";
    thing["_count"] = 123;
    thing["init"]("Unit Test", 123);

    Mặc dù có vẻ thú vị, TSC thực sự sẽ xác nhận các loại như thể bạn đã truy cập chúng trực tiếp:

    thing["_name"] = 123; // type error
    thing["_count"] = "Unit Test"; // type error
    thing["init"](0, "123"); // argument error

    Thành thật mà nói tôi không biết tại sao điều này hoạt động. Đây rõ ràng là một "lối thoát" cố ý để cung cấp cho bạn quyền truy cập vào các thành viên tư nhân mà không mất an toàn loại. Đây chính xác là những gì tôi nghĩ bạn muốn cho thử nghiệm đơn vị của bạn.

Dưới đây là một ví dụ hoạt động trong Sân chơi TypeScript .

Chỉnh sửa cho TypeScript 2.6

Một tùy chọn khác mà một số người thích là sử dụng // @ts-ignore( được thêm vào trong TS 2.6 ), đơn giản là loại bỏ tất cả các lỗi trên dòng sau:

// @ts-ignore
thing._name = "Unit Test";

Vấn đề với điều này là, nó sẽ loại bỏ tất cả các lỗi trên dòng sau:

// @ts-ignore
thing._name(123).this.should.NOT.beAllowed("but it is") = window / {};

Cá nhân tôi xem xét @ts-ignoremột mùi mã, và như các tài liệu nói:

chúng tôi khuyên bạn nên sử dụng ý kiến ​​này rất ít . [nhấn mạnh bản gốc]


45
Thật tuyệt khi nghe một lập trường thực tế về thử nghiệm đơn vị cùng với một giải pháp thực tế thay vì giáo điều thử nghiệm đơn vị tiêu chuẩn của bạn.
d512

2
Một số giải thích "chính thức" về hành vi (thậm chí trích dẫn thử nghiệm đơn vị là trường hợp sử dụng): github.com/microsoft/TypeScript/issues/19335
Aaron Beall

1
Chỉ cần sử dụng` // @ ts-ign` như được chỉ ra dưới đây. nói với người nói dối bỏ qua người truy cập riêng
Tommaso

1
@Tommaso Vâng, đó là một lựa chọn khác, nhưng có cùng nhược điểm khi sử dụng as any: bạn mất tất cả kiểm tra loại.
Aaron Beall

2
Câu trả lời hay nhất tôi từng thấy trong một thời gian, cảm ơn @AaronBeall. Và cũng, cảm ơn tymspy đã đặt câu hỏi ban đầu.
nicolas.leblanc

26

Bạn có thể gọi phương thức riêng tư . Nếu bạn gặp phải lỗi sau:

expect(new FooBar(/*...*/).initFooBar()).toEqual(/*...*/);
// TS2341: Property 'initFooBar' is private and only accessible within class 'FooBar'

chỉ sử dụng // @ts-ignore:

// @ts-ignore
expect(new FooBar(/*...*/).initFooBar()).toEqual(/*...*/);

cái này nên ở trên đỉnh
jsnewbie

2
Đây chắc chắn là một lựa chọn khác. Nó bị vấn đề tương tự như khi as anybạn mất bất kỳ kiểm tra loại nào, thực sự bạn mất bất kỳ kiểm tra loại nào trên toàn bộ dòng.
Aaron Beall

19

Vì hầu hết các nhà phát triển không khuyên bạn nên thử nghiệm chức năng riêng tư , Tại sao không thử nghiệm nó?.

Ví dụ.

YourClass.ts

export class FooBar {
  private _status: number;

  constructor( private foo : Bar ) {
    this.initFooBar({});
  }

  private initFooBar(data){
    this.foo.bar( data );
    this._status = this.foo.foo();
  }
}

TestYourClass.spec.ts

describe("Testing foo bar for status being set", function() {

...

//Variable with type any
let fooBar;

fooBar = new FooBar();

...
//Method 1
//Now this will be visible
fooBar.initFooBar();

//Method 2
//This doesn't require variable with any type
fooBar['initFooBar'](); 
...
}

Cảm ơn @Aaron, @Thierry Templier.


1
Tôi nghĩ rằng typcript đưa ra các lỗi linting khi bạn cố gắng gọi một phương thức riêng tư / được bảo vệ.
Gudgip

1
@Gudgip nó sẽ đưa ra lỗi loại và sẽ không biên dịch. :)
tymspy

10

Không viết bài kiểm tra cho các phương pháp riêng tư. Điều này đánh bại điểm kiểm tra đơn vị.

  • Bạn nên kiểm tra API công khai của lớp
  • Bạn KHÔNG nên kiểm tra các chi tiết bắt chước của lớp học của bạn

Thí dụ

class SomeClass {

  public addNumber(a: number, b: number) {
      return a + b;
  }
}

Thử nghiệm cho phương pháp này không cần phải thay đổi nếu sau đó việc triển khai thay đổi nhưng behaviourAPI công khai vẫn giữ nguyên.

class SomeClass {

  public addNumber(a: number, b: number) {
      return this.add(a, b);
  }

  private add(a: number, b: number) {
       return a + b;
  }
}

Đừng công khai các phương thức và thuộc tính để kiểm tra chúng. Điều này thường có nghĩa là:

  1. Bạn đang cố gắng thử nghiệm triển khai thay vì API (giao diện công cộng).
  2. Bạn nên chuyển logic trong câu hỏi vào lớp riêng của nó để làm cho việc kiểm tra dễ dàng hơn.

3
Có thể đọc bài viết trước khi bình luận về nó. Tôi nói rõ và chứng minh rằng kiểm tra tư nhân là một mùi của việc thực hiện kiểm tra hơn là hành vi, dẫn đến các kiểm tra dễ vỡ.
Martin

1
Tưởng tượng một đối tượng cung cấp cho bạn một số ngẫu nhiên trong khoảng từ 0 đến thuộc tính riêng x. Nếu bạn muốn biết nếu x được đặt chính xác bởi nhà xây dựng, việc kiểm tra giá trị của x sẽ dễ dàng hơn nhiều so với thực hiện hàng trăm thử nghiệm để kiểm tra xem các số bạn nhận được có nằm trong phạm vi phù hợp hay không.
Galdor

1
@ user3725805 đây là một ví dụ về kiểm tra việc thực hiện, không phải hành vi. Sẽ tốt hơn nếu cô lập nơi số riêng đến từ: hằng số, cấu hình, hàm tạo - và kiểm tra từ đó. Nếu cái riêng không đến từ một số nguồn khác, thì nó rơi vào antipotype "số ma thuật".
Martin

1
Và tại sao nó không được phép thử nghiệm việc thực hiện? Kiểm tra đơn vị là tốt để phát hiện những thay đổi bất ngờ. Khi vì lý do nào đó, nhà xây dựng quên đặt số, thử nghiệm thất bại ngay lập tức và cảnh báo tôi. Khi ai đó thay đổi việc thực hiện, bài kiểm tra cũng thất bại, nhưng tôi thích áp dụng một bài kiểm tra hơn là không có lỗi không bị phát hiện.
Galdor

2
+1. Câu trả lời chính xác. @TimJames Nói cách thực hành đúng hoặc chỉ ra cách tiếp cận thiếu sót là mục đích chính của SO. Thay vì tìm cách hacky-mong manh để đạt được bất cứ điều gì OP muốn.
Syed Aqeel Ashiq

4

Quan điểm của "không thử nghiệm các phương thức riêng tư" thực sự là Kiểm tra lớp giống như một người sử dụng nó .

Nếu bạn có API công khai với 5 phương thức, bất kỳ người tiêu dùng nào trong lớp của bạn đều có thể sử dụng các phương thức này và do đó bạn nên kiểm tra chúng. Một người tiêu dùng không nên truy cập các phương thức / thuộc tính riêng của lớp của bạn, nghĩa là bạn có thể thay đổi thành viên riêng khi chức năng tiếp xúc công khai giữ nguyên.


Nếu bạn dựa vào chức năng mở rộng nội bộ, hãy sử dụng protectedthay vì private.
Lưu ý rằng đó protectedvẫn là API công khai (!) , Chỉ được sử dụng khác nhau.

class OverlyComplicatedCalculator {
    public add(...numbers: number[]): number {
        return this.calculate((a, b) => a + b, numbers);
    }
    // can't be used or tested via ".calculate()", but it is still part of your public API!
    protected calculate(operation, operands) {
        let result = operands[0];
        for (let i = 1; i < operands.length; operands++) {
            result = operation(result, operands[i]);
        }
        return result;
    }
}

Kiểm tra đơn vị các thuộc tính được bảo vệ theo cùng một cách mà người tiêu dùng sẽ sử dụng chúng, thông qua phân lớp:

it('should be extensible via calculate()', () => {
    class TestCalculator extends OverlyComplicatedCalculator {
        public testWithArrays(array: any[]): any[] {
            const concat = (a, b) => [].concat(a, b);
            // tests the protected method
            return this.calculate(concat, array);
        }
    }
    let testCalc = new TestCalculator();
    let result = testCalc.testWithArrays([1, 'two', 3]);
    expect(result).toEqual([1, 'two', 3]);
});

3

Điều này làm việc cho tôi:

Thay vì:

sut.myPrivateMethod();

Điều này:

sut['myPrivateMethod']();

2

Xin lỗi vì sự hoại tử trên bài đăng này, nhưng tôi cảm thấy buộc phải cân nhắc một vài điều mà dường như không được chạm vào.

Trước hết - khi chúng tôi thấy mình cần truy cập vào các thành viên tư nhân trong một lớp trong quá trình kiểm tra đơn vị, thì đó thường là một lá cờ đỏ to, mập mà chúng tôi đã sử dụng trong cách tiếp cận chiến lược hoặc chiến thuật của mình và đã vô tình vi phạm nguyên tắc trách nhiệm duy nhất bằng cách đẩy hành vi nơi nó không thuộc về. Cảm thấy sự cần thiết phải truy cập các phương thức thực sự không có gì khác hơn một chương trình con bị cô lập của một quy trình xây dựng là một trong những sự cố phổ biến nhất của điều này; tuy nhiên, nó giống như sếp của bạn mong đợi bạn sẵn sàng cho công việc sẵn sàng và cũng có một số nhu cầu cần thiết để biết thói quen buổi sáng bạn đã trải qua để đưa bạn vào trạng thái đó ...

Trường hợp phổ biến nhất khác của điều này xảy ra là khi bạn thấy mình đang cố gắng kiểm tra "lớp thần" tục ngữ. Bản thân nó là một loại vấn đề đặc biệt, nhưng mắc phải cùng một vấn đề cơ bản với việc cần phải biết chi tiết thân mật của một thủ tục - nhưng đó là lạc đề.

Trong ví dụ cụ thể này, chúng tôi đã giao trách nhiệm khởi tạo đầy đủ đối tượng Bar cho hàm tạo của lớp FooBar. Trong lập trình hướng đối tượng, một trong những khách thuê cốt lõi là nhà xây dựng là "thiêng liêng" và cần được bảo vệ chống lại dữ liệu không hợp lệ sẽ làm mất hiệu lực trạng thái bên trong của chính nó và khiến nó bị thất bại ở một nơi khác ở phía dưới (trong đó có thể rất sâu đường ống dẫn.)

Chúng tôi đã không làm được điều đó ở đây bằng cách cho phép đối tượng FooBar chấp nhận một Bar chưa sẵn sàng tại thời điểm FooBar được xây dựng và đã bù đắp bằng cách "hack" đối tượng FooBar để đưa vấn đề vào chính nó tay.

Đây là kết quả của việc không tuân thủ một phần mười chương trình hướng đối tượng khác (trong trường hợp của Bar), đó là trạng thái của một đối tượng nên được khởi tạo hoàn toàn và sẵn sàng xử lý bất kỳ cuộc gọi đến nào cho các thành viên công khai của nó ngay sau khi tạo. Bây giờ, điều này không có nghĩa là ngay lập tức sau khi hàm tạo được gọi trong tất cả các trường hợp. Khi bạn có một đối tượng có nhiều kịch bản xây dựng phức tạp, thì tốt hơn là để lộ setters cho các thành viên tùy chọn của nó cho một đối tượng được triển khai theo mô hình thiết kế sáng tạo (Factory, Builder, v.v.) trong bất kỳ các trường hợp sau,

Trong ví dụ của bạn, thuộc tính "trạng thái" của Bar dường như không ở trạng thái hợp lệ trong đó FooBar có thể chấp nhận nó - vì vậy FooBar làm gì đó để khắc phục vấn đề đó.

Vấn đề thứ hai tôi đang thấy là có vẻ như bạn đang cố kiểm tra mã của mình chứ không phải thực hành phát triển dựa trên thử nghiệm. Đây chắc chắn là ý kiến ​​của riêng tôi tại thời điểm này; nhưng, loại thử nghiệm này thực sự là một mô hình chống. Điều cuối cùng bạn làm là rơi vào cái bẫy nhận ra rằng bạn có các vấn đề thiết kế cốt lõi khiến mã của bạn không thể kiểm tra được sau khi thực tế, thay vì viết các bài kiểm tra bạn cần và sau đó lập trình cho các bài kiểm tra. Dù bạn gặp phải vấn đề gì, bạn vẫn nên kết thúc với cùng số lượng thử nghiệm và dòng mã nếu bạn thực sự đạt được triển khai RẮN. Vì vậy - tại sao thử và đảo ngược kỹ thuật của bạn thành mã có thể kiểm tra khi bạn chỉ có thể giải quyết vấn đề khi bắt đầu nỗ lực phát triển của mình?

Nếu bạn đã làm điều đó, thì bạn sẽ nhận ra sớm hơn rằng bạn sẽ phải viết một số mã khá rắc rối để kiểm tra thiết kế của bạn và sẽ có cơ hội sớm để điều chỉnh lại cách tiếp cận của bạn bằng cách chuyển hành vi sang triển khai dễ dàng kiểm tra.


2

Tôi đồng ý với @toskv: Tôi không khuyên bạn nên làm điều đó :-)

Nhưng nếu bạn thực sự muốn kiểm tra phương thức riêng tư của mình, bạn có thể biết rằng mã tương ứng cho TypeScript tương ứng với một phương thức của nguyên mẫu hàm xây dựng. Điều này có nghĩa là nó có thể được sử dụng trong thời gian chạy (trong khi bạn có thể sẽ có một số lỗi biên dịch).

Ví dụ:

export class FooBar {
  private _status: number;

  constructor( private foo : Bar ) {
    this.initFooBar({});
  }

  private initFooBar(data){
    this.foo.bar( data );
    this._status = this.foo.foo();
  }
}

sẽ được dịch vào:

(function(System) {(function(__moduleName){System.register([], function(exports_1, context_1) {
  "use strict";
  var __moduleName = context_1 && context_1.id;
  var FooBar;
  return {
    setters:[],
    execute: function() {
      FooBar = (function () {
        function FooBar(foo) {
          this.foo = foo;
          this.initFooBar({});
        }
        FooBar.prototype.initFooBar = function (data) {
          this.foo.bar(data);
          this._status = this.foo.foo();
        };
        return FooBar;
      }());
      exports_1("FooBar", FooBar);
    }
  }
})(System);

Xem plunkr này: https://plnkr.co/edit/calJCF?p=preview .


1

Như nhiều người đã tuyên bố, nhiều như bạn muốn kiểm tra các phương thức riêng tư mà bạn không nên hack mã hoặc bộ chuyển mã để làm cho nó hoạt động cho bạn. TypeScript hiện đại sẽ từ chối hầu hết tất cả các bản hack mà mọi người đã cung cấp cho đến nay.


Giải pháp

TLDR ; nếu một phương thức nên được kiểm tra thì bạn nên tách mã thành một lớp mà bạn có thể đưa phương thức ra công khai để được kiểm tra.

Lý do bạn có phương thức riêng tư là vì chức năng không nhất thiết phải được phơi bày bởi lớp đó, và do đó nếu chức năng không thuộc về nó thì nó nên được tách ra thành lớp riêng của nó.

Thí dụ

Tôi đã xem qua bài viết này, một công việc tuyệt vời để giải thích cách bạn nên giải quyết thử nghiệm các phương pháp riêng tư. Nó thậm chí còn bao gồm một số phương pháp ở đây và tại sao chúng là những triển khai tồi.

https://patrickdesjardins.com/blog/how-to-unit-test-private-method-in-typescript-part-2

Lưu ý : Mã này được nâng lên từ blog được liên kết ở trên (Tôi đang sao chép trong trường hợp nội dung đằng sau liên kết thay đổi)

Trước
class User{
    public getUserInformationToDisplay(){
        //...
        this.getUserAddress();
        //...
    }

    private getUserAddress(){
        //...
        this.formatStreet();
        //...
    }
    private formatStreet(){
        //...
    }
}
Sau
class User{
    private address:Address;
    public getUserInformationToDisplay(){
        //...
        address.getUserAddress();
        //...
    }
}
class Address{
    private format: StreetFormatter;
    public format(){
        //...
        format.ToString();
        //...
    }
}
class StreetFormatter{
    public toString(){
        // ...
    }
}

1

gọi phương thức riêng bằng dấu ngoặc vuông

Tập tin Ts

class Calculate{
  private total;
  private add(a: number) {
      return a + total;
  }
}

tập tin Spectts

it('should return 5 if input 3 and 2', () => {
    component['total'] = 2;
    let result = component['add'](3);
    expect(result).toEqual(5);
});

0

Câu trả lời của Aaron là tốt nhất và đang làm việc cho tôi :) Tôi sẽ bỏ phiếu nhưng thật đáng buồn là tôi không thể (thiếu danh tiếng).

Tôi phải nói rằng thử nghiệm các phương thức riêng tư là cách duy nhất để sử dụng chúng và có mã sạch ở phía bên kia.

Ví dụ:

class Something {
  save(){
    const data = this.getAllUserData()
    if (this.validate(data))
      this.sendRequest(data)
  }
  private getAllUserData () {...}
  private validate(data) {...}
  private sendRequest(data) {...}
}

Sẽ rất có ý nghĩa khi không thử nghiệm tất cả các phương pháp này cùng một lúc bởi vì chúng ta sẽ cần phải chế nhạo những phương thức riêng tư đó, chúng ta không thể chế giễu vì chúng ta không thể truy cập chúng. Điều này có nghĩa là chúng ta cần rất nhiều cấu hình cho một bài kiểm tra đơn vị để kiểm tra toàn bộ điều này.

Điều này cho biết cách tốt nhất để kiểm tra phương pháp trên với tất cả các phụ thuộc là thử nghiệm kết thúc, bởi vì ở đây cần có thử nghiệm tích hợp, nhưng thử nghiệm E2E sẽ không giúp bạn nếu bạn đang thực hành TDD (Phát triển theo hướng thử nghiệm), nhưng thử nghiệm phương pháp nào cũng được.


0

Tuyến này tôi đi là một nơi tôi tạo các hàm bên ngoài lớp và gán hàm cho phương thức riêng của tôi.

export class MyClass {
  private _myPrivateFunction = someFunctionThatCanBeTested;
}

function someFunctionThatCanBeTested() {
  //This Is Testable
}

Bây giờ tôi không biết loại quy tắc OOP nào tôi vi phạm, nhưng để trả lời câu hỏi, đây là cách tôi kiểm tra các phương thức riêng tư. Tôi hoan nghênh bất cứ ai để tư vấn về ưu và nhược điểm này.

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.