Saya baru-baru ini berdiskusi dengan beberapa teman yang mana dari 2 metode berikut ini yang terbaik untuk mematikan hasil atau panggilan ke metode di dalam kelas yang sama dari metode di dalam kelas yang sama.
Ini adalah contoh yang sangat sederhana. Pada kenyataannya fungsinya jauh lebih kompleks.
Contoh:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionB()
{
return new Random().Next();
}
}
Jadi untuk menguji ini kita punya 2 metode.
Metode 1: Gunakan Fungsi dan Tindakan untuk mengganti fungsionalitas metode. Contoh:
public class MyClass
{
public Func<int> FunctionB { get; set; }
public MyClass()
{
FunctionB = FunctionBImpl;
}
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionBImpl()
{
return new Random().Next();
}
}
[TestClass]
public class MyClassTests
{
private MyClass _subject;
[TestInitialize]
public void Initialize()
{
_subject = new MyClass();
}
[TestMethod]
public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
{
_subject.FunctionB = () => 1;
var result = _subject.FunctionA();
Assert.IsFalse(result);
}
}
Metode 2: Buat anggota virtual, turunkan kelas dan di kelas turunan menggunakan Fungsi dan Tindakan untuk mengganti fungsionalitas Contoh:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected virtual int FunctionB()
{
return new Random().Next();
}
}
public class TestableMyClass
{
public Func<int> FunctionBFunc { get; set; }
public MyClass()
{
FunctionBFunc = base.FunctionB;
}
protected override int FunctionB()
{
return FunctionBFunc();
}
}
[TestClass]
public class MyClassTests
{
private TestableMyClass _subject;
[TestInitialize]
public void Initialize()
{
_subject = new TestableMyClass();
}
[TestMethod]
public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
{
_subject.FunctionBFunc = () => 1;
var result = _subject.FunctionA();
Assert.IsFalse(result);
}
}
Saya ingin tahu yang lebih baik dan MENGAPA?
Pembaruan: CATATAN: FunctionB juga bisa bersifat publik
FunctionB
rusak oleh desain. new Random().Next()
hampir selalu salah. Anda harus menyuntikkan instance dari Random
. ( Random
juga kelas yang dirancang dengan buruk, yang dapat menyebabkan beberapa masalah tambahan)
FunctionA
mengembalikan bool tetapi hanya menetapkan variabel lokalx
dan tidak mengembalikan apa pun.