Làm cách nào để sử dụng Assert để xác minh rằng một ngoại lệ đã bị ném?


830

Làm cách nào để sử dụng Assert(hoặc lớp Kiểm tra khác?) Để xác minh rằng một ngoại lệ đã bị ném?


Bạn đang sử dụng khung kiểm tra đơn vị nào?
Kevin Pullin

3
Visual Studio Tích hợp
Alex

4
Không có thuộc tính ExpectedException giúp đỡ? ref: msdn.microsoft.com/en-us/l
Library / Google

2
Thật buồn cười, tôi vừa hoàn thành việc tìm kiếm câu trả lời cho điều này, đã tìm thấy nó tại stackoverflow.com/questions/741029/testing-exceptions .
dfjacobs

Câu trả lời:


978

Đối với "Visual Studio Team Test", có vẻ như bạn áp dụng thuộc tính ExpectedException cho phương thức thử nghiệm.

Ví dụ từ tài liệu ở đây: Hướng dẫn kiểm tra đơn vị với Visual Studio Team Test

[TestMethod]
[ExpectedException(typeof(ArgumentException),
    "A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
   LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}

25
Thuộc tính ExpectedException ở trên cũng hoạt động trong NUnit (nhưng [TestMethod] phải là [Test]).
dbkk

5
@dbkk: Không hoạt động chính xác như nhau trong NUnit - tin nhắn được coi là một chuỗi cần matcvh thông báo ngoại lệ (và IU nghĩ điều đó có ý nghĩa hơn)
Ruben Bartelink

29
Thuộc tính này hoàn thành công việc và là một tính năng tích hợp sẵn cho các lập trình viên c #, nhưng tôi không khuyên bạn nên sử dụng nó vì nó không đủ linh hoạt. Xem xét những gì xảy ra nếu loại ngoại lệ được ném bởi mã thiết lập thử nghiệm của bạn: vượt qua thử nghiệm, nhưng thực tế không làm những gì bạn mong đợi. Hoặc nếu bạn muốn kiểm tra trạng thái của đối tượng ngoại lệ. Tôi thường muốn sử dụng StringAssert.Contains (e.Message ...) hơn là kiểm tra toàn bộ tin nhắn. Sử dụng một phương pháp khẳng định như được mô tả trong các câu trả lời khác.
steve

3
Tránh sử dụng ExpectedException trong NUnit, vì nó sẽ bị loại bỏ trong NUnit 3.0. Tôi thích sử dụng Assert.Throw <Cụ thể ngoại lệ> ()
Terence

5
Bạn có thể sử dụng Assert.ThrowsException <T> và Assert.ThrowsExceptionAsync <T> trong MsTest.
Gopal Krishnan

257

Thông thường khung thử nghiệm của bạn sẽ có câu trả lời cho việc này. Nhưng nếu nó không đủ linh hoạt, bạn luôn có thể làm điều này:

try {
    somethingThatShouldThrowAnException();
    Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (GoodException) { }

Như @Jonas chỉ ra, điều này KHÔNG hoạt động để bắt Ngoại lệ cơ sở:

try {
    somethingThatShouldThrowAnException();
    Assert.Fail(); // raises AssertionException
} catch (Exception) {
    // Catches the assertion exception, and the test passes
}

Nếu bạn hoàn toàn phải bắt Ngoại lệ, bạn cần phải lấy lại Assert.Fail (). Nhưng thực sự, đây là một dấu hiệu bạn không nên viết tay này; kiểm tra khung kiểm tra của bạn để biết các tùy chọn hoặc xem liệu bạn có thể đưa ra một ngoại lệ có ý nghĩa hơn để kiểm tra hay không.

catch (AssertionException) { throw; }

Bạn sẽ có thể điều chỉnh cách tiếp cận này với bất cứ điều gì bạn thích - bao gồm cả việc chỉ định loại ngoại lệ nào cần nắm bắt. Nếu bạn chỉ mong đợi một số loại nhất định, hãy kết thúc các catchkhối bằng:

} catch (GoodException) {
} catch (Exception) {
    // not the right kind of exception
    Assert.Fail();
}

20
+1, tôi sử dụng cách này thay vì thuộc tính khi tôi cần đưa ra các xác nhận ngoài loại ngoại lệ. Ví dụ: điều gì xảy ra nếu một người cần kiểm tra xem các trường nhất định trong trường hợp ngoại lệ được đặt thành các giá trị nhất định.
Pavel Repin

2
Bạn không cần phải chỉ định thông báo lỗi. Điều này là đủ: [ExpectedException (typeof (ArgumentException))]
mibollma

5
Tôi nghĩ rằng giải pháp này là tốt nhất. [ExpectedException (typeof (ArgumentException)) có sử dụng, nếu thử nghiệm đơn giản, nhưng theo quan điểm của tôi, một giải pháp lười biếng và việc thoải mái có thể dẫn đến những cạm bẫy. Giải pháp này cung cấp cho bạn quyền kiểm soát cụ thể để thực hiện kiểm tra chính xác hơn, ngoài ra bạn có thể kiểm tra Writeline vào báo cáo chạy thử nghiệm của mình, rằng ngoại lệ thực sự đã được ném như mong đợi.
cá ác

12
Hãy cẩn thận với điều đó bởi vì Assert.Fail () đưa ra một ngoại lệ, nếu bạn bắt được nó, vượt qua bài kiểm tra!
Jonas

4
@ Vinnyq12 Ý tôi là thử nghiệm đầu tiên trong ví dụ trên sẽ không bao giờ thất bại. Thử nghiệm thất bại nếu ném ngoại lệ (và không "bắt" bởi ExpectedExceptionAttribution)
Jonas

113

Phương pháp ưa thích của tôi để thực hiện điều này là viết một phương thức có tên là Ném và sử dụng nó giống như bất kỳ phương thức Khẳng định nào khác. Thật không may, .NET không cho phép bạn viết một phương thức mở rộng tĩnh, vì vậy bạn không thể sử dụng phương thức này như thể nó thực sự thuộc về bản dựng trong lớp Assert; chỉ cần làm một cái khác gọi là MyAssert hoặc một cái gì đó tương tự. Lớp học trông như thế này:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace YourProject.Tests
{
    public static class MyAssert
    {
        public static void Throws<T>( Action func ) where T : Exception
        {
            var exceptionThrown = false;
            try
            {
                func.Invoke();
            }
            catch ( T )
            {
                exceptionThrown = true;
            }

            if ( !exceptionThrown )
            {
                throw new AssertFailedException(
                    String.Format("An exception of type {0} was expected, but not thrown", typeof(T))
                    );
            }
        }
    }
}

Điều đó có nghĩa là bài kiểm tra đơn vị của bạn trông như thế này:

[TestMethod()]
public void ExceptionTest()
{
    String testStr = null;
    MyAssert.Throws<NullReferenceException>(() => testStr.ToUpper());
}

Mà trông và hành xử giống như nhiều cú pháp kiểm tra đơn vị còn lại của bạn.


1
Loại bỏ cờ bool và ném trực tiếp vào dòng sau khi gọi để thực hiện nhỏ gọn hơn.
gt

11
Điều duy nhất làm cho điều này tốt hơn là có hàm trả về ngoại lệ bị bắt để bạn có thể tiếp tục khẳng định rằng những thứ như các thuộc tính trên ngoại lệ là chính xác.
Đánh dấu Hildreth

2
Cảm ơn! Đây có vẻ là cách tiếp cận tốt nhất với tôi vì đó là một cách ngắn để kiểm tra nhiều ngoại lệ trong một phương pháp. Nó cũng dễ đọc hơn nhiều.
David Sherret

2
@MickeyPerlstein Thuộc tính phá vỡ các quy tắc AAA để thử nghiệm. Cụ thể, nếu Sắp xếp của bạn tình cờ ném ngoại lệ trước khi bạn thậm chí đến Đạo luật, thì bài kiểm tra của bạn sẽ vượt qua ... eek!
Freedomn-m

2
Microsoft cuối cùng đã có vòng để cập nhật MSTest - hỗ trợ v2 Assert.ThrowsException<T>Assert.ThrowsExceptionAsync<T>- xem blogs.msdn.microsoft.com/visualstudioalm/2017/02/25/...
Quango

62

nếu bạn sử dụng NUNIT, bạn có thể làm một cái gì đó như thế này:

Assert.Throws<ExpectedException>(() => methodToTest());


Cũng có thể lưu trữ ngoại lệ bị ném để xác thực nó thêm:

ExpectedException ex = Assert.Throws<ExpectedException>(() => methodToTest());
Assert.AreEqual( "Expected message text.", ex.Message );
Assert.AreEqual( 5, ex.SomeNumber);

Xem: http://nunit.org/docs/2.5/exceptionAsserts.html


60

Nếu bạn đang sử dụng MSTest, vốn ban đầu không có ExpectedExceptionthuộc tính, bạn có thể làm điều này:

try 
{
    SomeExceptionThrowingMethod()
    Assert.Fail("no exception thrown");
}
catch (Exception ex)
{
    Assert.IsTrue(ex is SpecificExceptionType);
}

3
Điều này không hoạt động, nhưng tôi không khuyến khích điều này nói chung vì logic quá phức tạp. Không nói rằng nó phức tạp, nhưng hãy xem xét nếu bạn viết khối mã này cho nhiều bài kiểm tra - 10, 100 bài kiểm tra. Logic này cần được đưa vào một phương pháp khẳng định được thiết kế tốt. Xem câu trả lời khác.
steve

35

Hãy cảnh giác khi sử dụng ExpectedException, vì nó có thể dẫn đến một số cạm bẫy như được trình bày ở đây:

http://geekswithbloss.net/sdorman/archive/2009/01/17/unit-testing-and-azed-exceptions.aspx

Và đây:

http://xunit.github.io/docs/comparisons.html

Nếu bạn cần kiểm tra các trường hợp ngoại lệ, sẽ có ít cách hơn. Bạn có thể sử dụng phương thức try {act / fail} Catch {assert}, có thể hữu ích cho các khung không có hỗ trợ trực tiếp cho các thử nghiệm ngoại lệ khác ngoài ExpectedException.

Một cách khác tốt hơn là sử dụng xUnit.NET, một khung kiểm tra đơn vị rất hiện đại, hướng tới tương lai và có thể mở rộng, đã học được từ tất cả các lỗi khác và được cải thiện. Một cải tiến như vậy là Assert.Throws, cung cấp một cú pháp tốt hơn nhiều để khẳng định các ngoại lệ.

Bạn có thể tìm thấy xUnit.NET tại github: http://xunit.github.io/


4
Lưu ý rằng NUnit 2.5 cũng hỗ trợ cú pháp Assert.Throws phong cách bây giờ quá - nunit.com/index.php?p=releaseNotes&r=2.5
Alconja

Cách mà các bài kiểm tra đơn vị dừng lại để cho bạn biết về ngoại lệ khi sử dụng ExpectedException khiến tôi phát điên. Tại sao MS nghĩ rằng đó là một ý tưởng tốt để có một bước thủ công trong các bài kiểm tra tự động? Cảm ơn các liên kết.
Kiến

@Ant: MS đã sao chép NUnit ... vậy câu hỏi thực sự là, tại sao NUnit nghĩ rằng đó là một ý tưởng tốt?
jrista

28

MSTest (v2) hiện có chức năng Assert.ThrowsException có thể được sử dụng như thế này:

Assert.ThrowsException<System.FormatException>(() =>
            {
                Story actual = PersonalSite.Services.Content.ExtractHeader(String.Empty);
            }); 

Bạn có thể cài đặt nó với nuget: Install-Package MSTest.TestFramework


Năm 2018, đây được coi là thực tiễn tốt nhất vì nó chỉ kiểm tra đơn vị đang thử nghiệm đang ném và không phải một số mã khác.
CM

24

Trong một dự án, tôi làm việc với chúng tôi có một giải pháp khác.

Đầu tiên tôi không dùng như ExpectedExceptionAttribution vì nó cần xem xét phương thức nào gây ra Ngoại lệ.

Tôi làm điều này với một helpermethod thay thế.

Kiểm tra

[TestMethod]
public void AccountRepository_ThrowsExceptionIfFileisCorrupt()
{
     var file = File.Create("Accounts.bin");
     file.WriteByte(1);
     file.Close();

     IAccountRepository repo = new FileAccountRepository();
     TestHelpers.AssertThrows<SerializationException>(()=>repo.GetAll());            
}

HelperMethod

public static TException AssertThrows<TException>(Action action) where TException : Exception
    {
        try
        {
            action();
        }
        catch (TException ex)
        {
            return ex;
        }
        Assert.Fail("Expected exception was not thrown");

        return null;
    }

Gọn gàng, không phải là nó;)


14

Đây là một thuộc tính trên phương thức thử nghiệm ... bạn không sử dụng Assert. Trông như thế này:

[ExpectedException(typeof(ExceptionType))]
public void YourMethod_should_throw_exception()

13

Bạn có thể tải xuống gói từ Nuget bằng cách sử dụng: PM> Cài đặt MSTestExtensions cài đặt thêm cú pháp Assert.Throws () theo kiểu nUnit / xUnit cho MsTest.

Hướng dẫn cấp cao: tải xuống bản lắp ráp và kế thừa từ BaseTest và bạn có thể sử dụng cú pháp Assert.Throws () .

Phương thức chính để thực hiện Ném như sau:

public static void Throws<T>(Action task, string expectedMessage, ExceptionMessageCompareOptions options) where T : Exception
{
    try
    {
        task();
    }
    catch (Exception ex)
    {
        AssertExceptionType<T>(ex);
        AssertExceptionMessage(ex, expectedMessage, options);
        return;
    }

    if (typeof(T).Equals(new Exception().GetType()))
    {
        Assert.Fail("Expected exception but no exception was thrown.");
    }
    else
    {
        Assert.Fail(string.Format("Expected exception of type {0} but no exception was thrown.", typeof(T)));
    }
}

Tiết lộ: Tôi kết hợp gói này.

Thông tin thêm: http://www.bradoncode.com/blog/2012/01/asserting-exceptions-in-mstest-with.html


Cảm ơn ví dụ. Bạn có ví dụ về cách kiểm tra Assert.DoesNotThrow () hoặc tương đương không?
Lane Goolsby

10

Bạn có thể đạt được điều này với một dòng đơn giản.

Nếu hoạt động của bạn không đồng bộ foo.bar():

await Assert.ThrowsExceptionAsync<Exception>(() => foo.bar());

Nếu foo.bar()không đồng bộ

Assert.ThrowsException<Exception>(() => foo.bar());

1
Có rất nhiều câu trả lời khác, đối với tôi, tôi đang tìm kiếm một cách tốc ký để kiểm tra các điều kiện thất bại đã biết chỉ bằng Loại ngoại lệ, điều này làm cho các trường hợp kiểm tra dễ đọc nhất. LƯU Ý: Loại ngoại lệ không khớp với các lớp ngoại lệ được kế thừa như một lần thử tiêu chuẩn, vì vậy ví dụ trên sẽ không bẫy ArgumentExceptionví dụ. Thử Catch cũ và kiểm tra phản hồi ngoại lệ vẫn được ưu tiên nếu bạn có tiêu chí nâng cao để kiểm tra, nhưng đối với nhiều trường hợp của tôi, điều này giúp ích rất nhiều!
Chris Schaller

5

Tôi không khuyên bạn nên sử dụng thuộc tính ExpectedException (vì nó quá hạn chế và dễ bị lỗi) hoặc để viết một khối thử / bắt trong mỗi thử nghiệm (vì nó quá phức tạp và dễ bị lỗi). Sử dụng một phương pháp khẳng định được thiết kế tốt - được cung cấp bởi khung kiểm tra của bạn hoặc tự viết. Đây là những gì tôi đã viết và sử dụng.

public static class ExceptionAssert
{
    private static T GetException<T>(Action action, string message="") where T : Exception
    {
        try
        {
            action();
        }
        catch (T exception)
        {
            return exception;
        }
        throw new AssertFailedException("Expected exception " + typeof(T).FullName + ", but none was propagated.  " + message);
    }

    public static void Propagates<T>(Action action) where T : Exception
    {
        Propagates<T>(action, "");
    }

    public static void Propagates<T>(Action action, string message) where T : Exception
    {
        GetException<T>(action, message);
    }

    public static void Propagates<T>(Action action, Action<T> validation) where T : Exception
    {
        Propagates(action, validation, "");
    }

    public static void Propagates<T>(Action action, Action<T> validation, string message) where T : Exception
    {
        validation(GetException<T>(action, message));
    }
}

Ví dụ sử dụng:

    [TestMethod]
    public void Run_PropagatesWin32Exception_ForInvalidExeFile()
    {
        (test setup that might propagate Win32Exception)
        ExceptionAssert.Propagates<Win32Exception>(
            () => CommandExecutionUtil.Run(Assembly.GetExecutingAssembly().Location, new string[0]));
        (more asserts or something)
    }

    [TestMethod]
    public void Run_PropagatesFileNotFoundException_ForExecutableNotFound()
    {
        (test setup that might propagate FileNotFoundException)
        ExceptionAssert.Propagates<FileNotFoundException>(
            () => CommandExecutionUtil.Run("NotThere.exe", new string[0]),
            e => StringAssert.Contains(e.Message, "NotThere.exe"));
        (more asserts or something)
    }

GHI CHÚ

Trả lại ngoại lệ thay vì hỗ trợ gọi lại xác thực là một ý tưởng hợp lý ngoại trừ việc làm như vậy làm cho cú pháp gọi của khẳng định này rất khác so với các xác nhận khác mà tôi sử dụng.

Không giống như những người khác, tôi sử dụng 'tuyên truyền' thay vì 'ném' vì chúng tôi chỉ có thể kiểm tra xem một ngoại lệ có lan truyền từ một cuộc gọi hay không. Chúng tôi không thể kiểm tra trực tiếp rằng một ngoại lệ được ném ra. Nhưng tôi cho rằng bạn có thể ném hình ảnh có nghĩa là: ném và không bị bắt.

CUỐI CÙNG

Trước khi chuyển sang cách tiếp cận này, tôi đã cân nhắc sử dụng thuộc tính ExpectedException khi kiểm tra chỉ xác minh loại ngoại lệ và sử dụng khối thử / bắt nếu cần thêm xác thực. Nhưng, tôi không chỉ phải suy nghĩ về việc sử dụng kỹ thuật nào cho mỗi thử nghiệm, mà việc thay đổi mã từ kỹ thuật này sang kỹ thuật khác vì nhu cầu thay đổi không phải là nỗ lực tầm thường. Sử dụng một phương pháp nhất quán giúp tiết kiệm nỗ lực tinh thần.

Vì vậy, tóm lại, cách tiếp cận này thể thao: dễ sử dụng, linh hoạt và mạnh mẽ (khó làm sai).


4

Trình trợ giúp được cung cấp bởi @Richiban ở trên hoạt động rất tốt trừ việc nó không xử lý tình huống ném ngoại lệ, nhưng không phải là loại được mong đợi. Các địa chỉ sau:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace YourProject.Tests
{
    public static class MyAssert
    {
        /// <summary>
        /// Helper for Asserting that a function throws an exception of a particular type.
        /// </summary>
        public static void Throws<T>( Action func ) where T : Exception
        {
            Exception exceptionOther = null;
            var exceptionThrown = false;
            try
            {
                func.Invoke();
            }
            catch ( T )
            {
                exceptionThrown = true;
            }
            catch (Exception e) {
                exceptionOther = e;
            }

            if ( !exceptionThrown )
            {
                if (exceptionOther != null) {
                    throw new AssertFailedException(
                        String.Format("An exception of type {0} was expected, but not thrown. Instead, an exception of type {1} was thrown.", typeof(T), exceptionOther.GetType()),
                        exceptionOther
                        );
                }

                throw new AssertFailedException(
                    String.Format("An exception of type {0} was expected, but no exception was thrown.", typeof(T))
                    );
            }
        }
    }
}

2
Hmmm ... tôi hiểu ý tưởng, nhưng tôi không chắc là tôi đồng ý nó tốt hơn. Chỉ vì chúng tôi muốn đảm bảo một ngoại lệ cụ thể được nêu ra không có nghĩa là tất cả những người khác nên được coi là một thất bại khẳng định. IMHO một ngoại lệ không xác định sẽ chỉ tạo bong bóng cho ngăn xếp như trong bất kỳ hoạt động khẳng định nào khác.
Crono

@Martin Tôi sẽ xóa mã liên quan đến ngoại lệ Khác và đơn giản là rút lại từ mệnh đề bắt thứ hai
Tom Lint

4

Vì bạn đề cập đến việc sử dụng các lớp kiểm tra khác, nên một tùy chọn tốt hơn ExpectedExceptionthuộc tính là sử dụng Should.Throw của Shoudly .

Should.Throw<DivideByZeroException>(() => { MyDivideMethod(1, 0); });

Giả sử chúng tôi có một yêu cầu là khách hàng phải có địa chỉ để tạo đơn hàng . Nếu không, CreateOrderForCustomerphương pháp sẽ dẫn đến một ArgumentException. Sau đó chúng ta có thể viết:

[TestMethod]
public void NullUserIdInConstructor()
{
  var customer = new Customer(name := "Justin", address := null};

  Should.Throw<ArgumentException>(() => {
    var order = CreateOrderForCustomer(customer) });
}

Điều này tốt hơn là sử dụng một ExpectedException thuộc tính bởi vì chúng tôi đang cụ thể về những gì sẽ gây ra lỗi. Điều này làm cho các yêu cầu trong các xét nghiệm của chúng tôi rõ ràng hơn và cũng giúp chẩn đoán dễ dàng hơn khi thử nghiệm thất bại.

Lưu ý rằng cũng có một Should.ThrowAsyncthử nghiệm phương pháp không đồng bộ.


4

Để thay thế, bạn có thể thử kiểm tra các ngoại lệ trong thực tế đang bị ném với 2 dòng tiếp theo trong bài kiểm tra của bạn.

var testDelegate = () => MyService.Method(params);
Assert.Throws<Exception>(testDelegate);

4

Trong thử nghiệm đơn vị tích hợp sẵn của VS nếu bạn chỉ muốn xác minh rằng "bất kỳ ngoại lệ" nào được đưa ra, nhưng bạn không biết loại, bạn có thể sử dụng tất cả:

[TestMethod]
[ExpectedException(typeof(Exception), AllowDerivedTypes = true)]
public void ThrowExceptionTest()
{
    //...
}

3

Chà, tôi sẽ tổng hợp khá nhiều những gì mọi người khác ở đây đã nói trước đây ... Dù sao, đây là đoạn mã tôi xây dựng theo câu trả lời hay :) Tất cả những gì còn lại phải làm là sao chép và sử dụng ...

/// <summary>
/// Checks to make sure that the input delegate throws a exception of type TException.
/// </summary>
/// <typeparam name="TException">The type of exception expected.</typeparam>
/// <param name="methodToExecute">The method to execute to generate the exception.</param>
public static void AssertRaises<TException>(Action methodToExecute) where TException : System.Exception
{
    try
    {
        methodToExecute();
    }
    catch (TException) {
        return;
    }  
    catch (System.Exception ex)
    {
        Assert.Fail("Expected exception of type " + typeof(TException) + " but type of " + ex.GetType() + " was thrown instead.");
    }
    Assert.Fail("Expected exception of type " + typeof(TException) + " but no exception was thrown.");  
}


2

Điều này sẽ phụ thuộc vào khung kiểm tra mà bạn đang sử dụng?

Ví dụ, trong MbUnit, bạn có thể chỉ định ngoại lệ dự kiến ​​với một thuộc tính để đảm bảo rằng bạn đang nhận được ngoại lệ mà bạn thực sự mong đợi.

[ExpectedException(typeof(ArgumentException))]

2

Trong trường hợp sử dụng NUnit , hãy thử điều này:

Assert.That(() =>
        {
            Your_Method_To_Test();
        }, Throws.TypeOf<Your_Specific_Exception>().With.Message.EqualTo("Your_Specific_Message"));

2

Có một thư viện tuyệt vời tên là NFluent giúp tăng tốc và giảm bớt cách bạn viết các xác nhận của mình .

Thật đơn giản để viết một khẳng định cho việc ném một ngoại lệ:

    [Test]
    public void given_when_then()
    {
        Check.ThatCode(() => MethodToTest())
            .Throws<Exception>()
            .WithMessage("Process has been failed");
    }

1

Mặc dù đây là một câu hỏi cũ, tôi muốn thêm một ý nghĩ mới vào cuộc thảo luận. Tôi đã mở rộng mô hình Arrange, Act, Assert được mong đợi, Sắp xếp, Act, Assert. Bạn có thể tạo một con trỏ ngoại lệ dự kiến, sau đó xác nhận nó được gán cho. Điều này cảm thấy sạch sẽ hơn so với thực hiện các Xác nhận của bạn trong một khối bắt, để lại phần Act của bạn chủ yếu chỉ cho một dòng mã để gọi phương thức đang thử nghiệm. Bạn cũng không phải Assert.Fail();hoặc returntừ nhiều điểm trong mã. Bất kỳ ngoại lệ nào khác được ném sẽ khiến bài kiểm tra thất bại, vì nó sẽ không bị bắt và nếu một ngoại lệ của loại dự kiến ​​của bạn bị ném, nhưng đó không phải là trường hợp bạn mong đợi, Khẳng định chống lại tin nhắn hoặc các thuộc tính khác của ngoại lệ giúp đảm bảo bài kiểm tra của bạn sẽ không vô tình vượt qua.

[TestMethod]
public void Bar_InvalidDependency_ThrowsInvalidOperationException()
{
    // Expectations
    InvalidOperationException expectedException = null;
    string expectedExceptionMessage = "Bar did something invalid.";

    // Arrange
    IDependency dependency = DependencyMocks.Create();
    Foo foo = new Foo(dependency);

    // Act
    try
    {
        foo.Bar();
    }
    catch (InvalidOperationException ex)
    {
        expectedException = ex;
    }

    // Assert
    Assert.IsNotNull(expectedException);
    Assert.AreEqual(expectedExceptionMessage, expectedException.Message);
}
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.