Saya sedang menulis tes unit untuk satu metode ini yang mengembalikan "void". Saya ingin memiliki satu kasus yang lulus uji ketika tidak ada pengecualian yang dilemparkan. Bagaimana cara menulisnya di C #?
Assert.IsTrue(????)
(Dugaan saya adalah begini cara saya memeriksanya, tapi yang berbunyi "???")
Saya harap pertanyaan saya cukup jelas.
c#
unit-testing
exception
mstest
George yang penasaran
sumber
sumber
Jawaban:
Tes unit Anda akan tetap gagal jika pengecualian dilemparkan - Anda tidak perlu memasukkan pernyataan khusus.
Ini adalah salah satu dari sedikit skenario di mana Anda akan melihat pengujian unit tanpa pernyataan sama sekali - pengujian secara implisit akan gagal jika pengecualian dimunculkan.
Namun, jika Anda benar-benar ingin menulis pernyataan untuk ini - mungkin agar dapat menangkap pengecualian dan melaporkan "tidak mengharapkan pengecualian tetapi mendapatkan ini ...", Anda dapat melakukan ini:
[Test] public void TestNoExceptionIsThrownByMethodUnderTest() { var myObject = new MyObject(); try { myObject.MethodUnderTest(); } catch (Exception ex) { Assert.Fail("Expected no exception, but got: " + ex.Message); } }
(di atas adalah contoh untuk NUnit, tetapi hal yang sama berlaku untuk MSTest)
sumber
Di NUnit, Anda dapat menggunakan:
untuk menegaskan bahwa kode Anda tidak memunculkan pengecualian. Meskipun pengujian akan gagal jika pengecualian ditampilkan meskipun tidak ada Assert di sekitarnya, nilai dari pendekatan ini adalah Anda kemudian dapat membedakan antara ekspektasi yang tidak terpenuhi dan bug dalam pengujian Anda, dan Anda memiliki opsi untuk menambahkan pesan kustom yang akan ditampilkan dalam hasil tes Anda. Hasil pengujian yang dirancang dengan baik dapat membantu Anda menemukan kesalahan dalam kode yang menyebabkan pengujian gagal.
Menurut saya, menambahkan pengujian untuk memastikan bahwa kode Anda tidak memberikan pengecualian adalah valid; misalnya, bayangkan Anda memvalidasi input dan perlu mengubah string yang masuk menjadi string panjang. Mungkin ada kalanya string adalah null, dan ini dapat diterima, jadi Anda ingin memastikan bahwa konversi string tidak memunculkan pengecualian. Oleh karena itu akan ada kode untuk menangani kesempatan ini, dan jika Anda belum menulis tes untuk itu, Anda akan kehilangan liputan seputar bagian penting dari logika.
sumber
public class TestBase { //believe me, I don't like this anymore than you do. protected void AssertDoesNotThrow(Action action, string message) { try { action(); } catch (Exception) { Assert.Fail(message); } } }
Jangan menguji bahwa sesuatu tidak terjadi . Ini seperti memastikan bahwa kode tidak rusak . Itu semacam tersirat, kita semua berjuang untuk kode tanpa-kerusakan, tanpa bug. Anda ingin menulis tes untuk itu? Mengapa hanya satu metode? Tidakkah Anda ingin semua metode Anda diuji sehingga tidak ada pengecualian ? Setelah jalan itu, Anda akan mendapatkan satu pengujian ekstra, dummy, dan tanpa pernyataan untuk setiap metode dalam basis kode Anda. Itu tidak ada nilainya.
Tentu saja, jika persyaratan Anda adalah untuk memverifikasi bahwa metode tidak menangkap pengecualian , Anda menguji itu (atau membalikkannya sedikit; uji bahwa itu tidak membuang apa yang seharusnya ditangkap).
Namun, pendekatan / praktik umum tetap utuh - Anda tidak menulis pengujian untuk beberapa persyaratan buatan / samar yang berada di luar cakupan kode yang diuji (dan pengujian bahwa "berfungsi" atau "tidak melempar" biasanya merupakan contoh dari seperti - terutama dalam skenario ketika tanggung jawab metode diketahui dengan baik).
Sederhananya - fokuslah pada apa yang harus dilakukan kode Anda dan uji untuk itu.
sumber
Kelas pembantu ini membuat saya gatal dengan MSTest. Mungkin itu bisa menggores milikmu juga.
[TestMethod] public void ScheduleItsIneligibilityJob_HasValid_CronSchedule() { // Arrange var factory = new StdSchedulerFactory(); IScheduler scheduler = factory.GetScheduler(); // Assert AssertEx.NoExceptionThrown<FormatException>(() => // Act _service.ScheduleJob(scheduler) ); } public sealed class AssertEx { public static void NoExceptionThrown<T>(Action a) where T:Exception { try { a(); } catch (T) { Assert.Fail("Expected no {0} to be thrown", typeof(T).Name); } } }
sumber
Assert
memiliki pengakses properti tunggal,That
yang dapat digunakan sebagai pengait untuk metode ekstensi. Mungkin lebih rapi, dan lebih mudah ditemukan,Assert.That.DoesNotThrow()
daripada memilikinyaAssertEx.DoesNotThrow()
. Ini hanya opini.Saya suka melihat
Assert.Whatever
di akhir setiap tes, hanya untuk konsistensi ... tanpa tes, apakah saya benar-benar yakin tidak seharusnya ada tes di sana?Bagi saya, ini sesederhana meletakkan
Assert.IsTrue(true);
Saya tahu saya tidak sengaja memasukkan kode itu ke sana, dan karena itu saya harus cukup percaya diri dengan membaca sekilas bahwa ini seperti yang dimaksudkan.
[TestMethod] public void ProjectRejectsGappedVersioningByDefault() { var files = new List<ScriptFile>(); files.Add(ScriptProjectTestMocks.GetVersion1to2()); files.Add(ScriptProjectTestMocks.GetVersion3to4()); Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => { var sut = new ScriptProject(files); }); } [TestMethod] public void ProjectAcceptsGappedVersionsExplicitly() { var files = new List<ScriptFile>(); files.Add(ScriptProjectTestMocks.GetVersion1to2()); files.Add(ScriptProjectTestMocks.GetVersion3to4()); var sut = new ScriptProject(files, true); Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like }
sumber
Teman saya, Tim, memberi tahu saya tentang ExpectedException . Saya sangat suka b / c ini karena lebih ringkas, lebih sedikit kode, dan sangat eksplisit bahwa Anda menguji pengecualian.
[TestMethod()] [ExpectedException(typeof(System.Exception))] public void DivideTest() { int numerator = 4; int denominator = 0; int actual = numerator / denominator; }
Anda dapat membaca lebih lanjut tentang itu di sini: Penggunaan Atribut ExpectedException .
sumber