Bagaimana cara memverifikasi bahwa metode dipanggil tepat sekali dengan Moq? Hal Verify()
vs. Verifable()
benar-benar membingungkan.
Bagaimana cara memverifikasi bahwa metode dipanggil tepat sekali dengan Moq? Hal Verify()
vs. Verifable()
benar-benar membingungkan.
Jawaban:
Anda dapat menggunakan Times.Once()
, atau Times.Exactly(1)
:
mockContext.Verify(x => x.SaveChanges(), Times.Once());
mockContext.Verify(x => x.SaveChanges(), Times.Exactly(1));
Berikut adalah metode di kelas Times :
AtLeast
- Menentukan bahwa metode tiruan harus dipanggil sesingkat mungkin.AtLeastOnce
- Menentukan bahwa metode tiruan harus dipanggil minimal satu kali.AtMost
- Menentukan bahwa metode tiruan harus dipanggil waktu maksimum.AtMostOnce
- Menentukan bahwa metode tiruan harus dipanggil satu kali sebagai maksimum.Between
- Menentukan bahwa metode tiruan harus dipanggil antara dari dan ke waktu.Exactly
- Menentukan bahwa metode tiruan harus dipanggil tepat waktu.Never
- Menentukan bahwa metode tiruan tidak boleh dipanggil.Once
- Menentukan bahwa metode tiruan harus dipanggil tepat satu kali.Ingatlah bahwa mereka adalah pemanggilan metode; Saya terus tersandung, mengira itu properti dan melupakan tanda kurung.
var mockContext = new Mock<IContext>()
mengaturnya.
AtLeast
, AtMost
, Between
, atau Exactly
bisa dilihat sebagai properti. Maksud saya, mereka pasti membutuhkan parameter untuk melakukan sesuatu.
Bayangkan kita sedang membangun kalkulator dengan satu metode untuk menambahkan 2 bilangan bulat. Mari kita bayangkan lebih lanjut persyaratannya adalah ketika metode add dipanggil, ia memanggil metode cetak sekali. Berikut adalah cara kami menguji ini:
public interface IPrinter
{
void Print(int answer);
}
public class ConsolePrinter : IPrinter
{
public void Print(int answer)
{
Console.WriteLine("The answer is {0}.", answer);
}
}
public class Calculator
{
private IPrinter printer;
public Calculator(IPrinter printer)
{
this.printer = printer;
}
public void Add(int num1, int num2)
{
printer.Print(num1 + num2);
}
}
Dan inilah tes sebenarnya dengan komentar di dalam kode untuk klarifikasi lebih lanjut:
[TestClass]
public class CalculatorTests
{
[TestMethod]
public void WhenAddIsCalled__ItShouldCallPrint()
{
/* Arrange */
var iPrinterMock = new Mock<IPrinter>();
// Let's mock the method so when it is called, we handle it
iPrinterMock.Setup(x => x.Print(It.IsAny<int>()));
// Create the calculator and pass the mocked printer to it
var calculator = new Calculator(iPrinterMock.Object);
/* Act */
calculator.Add(1, 1);
/* Assert */
// Let's make sure that the calculator's Add method called printer.Print. Here we are making sure it is called once but this is optional
iPrinterMock.Verify(x => x.Print(It.IsAny<int>()), Times.Once);
// Or we can be more specific and ensure that Print was called with the correct parameter.
iPrinterMock.Verify(x => x.Print(3), Times.Once);
}
}
Catatan : Secara default Moq akan menghentikan semua properti dan metode segera setelah Anda membuat objek Mock. Jadi bahkan tanpa menelepon Setup
, Moq telah mematikan metode IPrinter
sehingga Anda bisa menelepon Verify
. Namun, sebagai praktik yang baik, saya selalu menyiapkannya karena kita mungkin perlu menerapkan parameter ke metode untuk memenuhi ekspektasi tertentu, atau nilai kembalian dari metode untuk memenuhi ekspektasi tertentu atau berapa kali ia dipanggil.
Verify
, Times.Once
tanpa pernah menelepon Setup
. Saya pasti berharap Verify
untuk meledak dalam kasus itu, tetapi ternyata tidak.
Mock
objek. Jadi bahkan tanpa menelepon Setup
, Moq telah mematikan metode IPrinter
sehingga Anda bisa menelepon Verify
. Namun, sebagai praktik yang baik, saya selalu menyiapkannya karena kita mungkin perlu menerapkan parameter ke metode atau nilai kembalian dari metode tersebut.
Times.Exactly(1)
dan tidak gagal ketika metode itu sebenarnya dipanggil dua kali. Hanya setelah menambahkan Setup
metode yang dimaksud apakah itu gagal dengan benar.
Pengontrol uji dapat berupa:
public HttpResponseMessage DeleteCars(HttpRequestMessage request, int id)
{
Car item = _service.Get(id);
if (item == null)
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
_service.Remove(id);
return request.CreateResponse(HttpStatusCode.OK);
}
Dan ketika metode DeleteCars dipanggil dengan id yang valid, maka kita dapat memverifikasi itu, Metode penghapusan layanan dipanggil tepat sekali oleh tes ini:
[TestMethod]
public void Delete_WhenInvokedWithValidId_ShouldBeCalledRevomeOnce()
{
//arange
const int carid = 10;
var car = new Car() { Id = carid, Year = 2001, Model = "TTT", Make = "CAR 1", Price=2000 };
mockCarService.Setup(x => x.Get(It.IsAny<int>())).Returns(car);
var httpRequestMessage = new HttpRequestMessage();
httpRequestMessage.Properties[HttpPropertyKeys.HttpConfigurationKey] = new HttpConfiguration();
//act
var result = carController.DeleteCar(httpRequestMessage, vechileId);
//assert
mockCarService.Verify(x => x.Remove(carid), Times.Exactly(1));
}