Saya telah berjuang dengan masalah yang semakin menjengkelkan terkait tes unit kami yang kami terapkan di tim saya. Kami berusaha menambahkan unit test ke dalam kode legacy yang tidak dirancang dengan baik dan sementara kami belum mengalami kesulitan dengan penambahan tes yang sebenarnya, kami mulai bergumul dengan bagaimana hasil tes tersebut.
Sebagai contoh masalah, katakanlah Anda memiliki metode yang memanggil 5 metode lain sebagai bagian dari pelaksanaannya. Tes untuk metode ini mungkin untuk mengkonfirmasi bahwa suatu perilaku terjadi sebagai hasil dari salah satu dari 5 metode lain yang dipanggil. Jadi, karena unit test harus gagal karena satu alasan dan hanya satu alasan, Anda ingin menghilangkan masalah potensial yang disebabkan oleh memanggil 4 metode lainnya dan mengejeknya. Besar! Tes unit dijalankan, metode yang diejek diabaikan (dan perilakunya dapat dikonfirmasi sebagai bagian dari pengujian unit lainnya), dan verifikasi berfungsi.
Tapi ada masalah baru - unit test memiliki pengetahuan mendalam tentang bagaimana Anda mengkonfirmasi bahwa perilaku dan setiap tanda tangan berubah ke salah satu dari 4 metode lain di masa depan, atau metode baru yang perlu ditambahkan ke 'metode induk', akan mengakibatkan harus mengubah unit test untuk menghindari kemungkinan kegagalan.
Tentu saja masalahnya dapat dikurangi sedikit dengan hanya memiliki lebih banyak metode menyelesaikan perilaku lebih sedikit tapi saya berharap mungkin ada solusi yang lebih elegan yang tersedia.
Berikut ini adalah contoh unit test yang menangkap masalah.
Sebagai catatan singkat, 'MergeTests' adalah kelas pengujian unit yang mewarisi dari kelas yang kami uji dan menimpa perilaku yang diperlukan. Ini adalah 'pola' yang kami gunakan dalam pengujian kami untuk memungkinkan kami mengesampingkan panggilan ke kelas / dependensi eksternal.
[TestMethod]
public void VerifyMergeStopsSpinner()
{
var mockViewModel = new Mock<MergeTests> { CallBase = true };
var mockMergeInfo = new MergeInfo(Mock.Of<IClaim>(), Mock.Of<IClaim>(), It.IsAny<bool>());
mockViewModel.Setup(m => m.ClaimView).Returns(Mock.Of<IClaimView>);
mockViewModel.Setup(
m =>
m.TryMergeClaims(It.IsAny<Func<bool>>(), It.IsAny<IClaim>(), It.IsAny<IClaim>(), It.IsAny<bool>(),
It.IsAny<bool>()));
mockViewModel.Setup(m => m.GetSourceClaimAndTargetClaimByMergeState(It.IsAny<MergeState>())).Returns(mockMergeInfo);
mockViewModel.Setup(m => m.SwitchToOverviewTab());
mockViewModel.Setup(m => m.IncrementSaveRequiredNotification());
mockViewModel.Setup(m => m.OnValidateAndSaveAll(It.IsAny<object>()));
mockViewModel.Setup(m => m.ProcessPendingActions(It.IsAny<string>()));
mockViewModel.Object.OnMerge(It.IsAny<MergeState>());
mockViewModel.Verify(mvm => mvm.StopSpinner(), Times.Once());
}
Bagaimana Anda semua berurusan dengan ini atau tidak ada cara 'sederhana' yang hebat untuk menanganinya?
Pembaruan - Saya menghargai umpan balik semua orang. Sayangnya, dan itu tidak mengherankan, sepertinya tidak ada solusi, pola, atau praktik yang dapat diikuti seseorang dalam pengujian unit jika kode yang diuji buruk. Saya menandai jawaban yang paling tepat menangkap kebenaran sederhana ini.