Moq kullanarak ve baktım Callbackama nasıl kullanılacağını anlamak için basit bir örnek bulamadım.
Nasıl ve ne zaman kullanılacağını net bir şekilde açıklayan küçük bir çalışma pasajınız var mı?
Moq kullanarak ve baktım Callbackama nasıl kullanılacağını anlamak için basit bir örnek bulamadım.
Nasıl ve ne zaman kullanılacağını net bir şekilde açıklayan küçük bir çalışma pasajınız var mı?
Yanıtlar:
Yenmek zor https://github.com/Moq/moq4/wiki/Quickstart
Yeterince açık değilse, buna doc bug derim ...
DÜZENLEME: Açıklamanıza yanıt olarak ...
SetupYaptığınız her alay yöntemi için, aşağıdaki gibi şeyler belirtebilirsiniz:
.CallbackMekanizma "Şu an tarif edemez, ancak bu şeklinde bir çağrı olduğunda, beni geri arayıp yapılması gerekenleri yapacağız" diyor. Aynı akıcı çağrı zincirinin bir parçası olarak, sonucu (varsa) .Returns" yoluyla kontrol edebilirsiniz . QS örneklerinde, bir örnek, döndürülen değeri her seferinde artırmalarıdır.
Genel olarak, bunun gibi bir mekanizmaya çok sık ihtiyaç duymazsınız (xUnit Test Patterns, Koşullu Mantık Testlerindeki antipattern terimlerine sahiptir) ve ihtiyacınız olanı oluşturmanın daha basit veya yerleşik bir yolu varsa, tercih olarak kullanılır.
Justin Etheredge'in Moq serisindeki 4 bölümden 3'ü bunu kapsıyor ve burada başka bir geri arama örneği var
Geri aramanın basit bir örneği Moq gönderisiyle Geri Aramaları Kullanma'da bulunabilir .
Callbackdönüş değeriyle hiçbir ilgisi yok (kod aracılığıyla bağlamadığınız sürece). Temel olarak, yalnızca geri aramanın her çağrıdan önce veya sonra çağrıldığından emin olur ( Returnssırasıyla önce veya sonra zincirlemenize bağlı olarak), düz ve basittir.
Aşağıda, bir eki işleyen bir Veri Hizmetine gönderilen bir varlığı test etmek için geri arama kullanımına bir örnek verilmiştir.
var mock = new Mock<IDataService>();
DataEntity insertedEntity = null;
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback((DataEntity de) => insertedEntity = de);
Alternatif genel yöntem sözdizimi:
mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1)
.Callback<DataEntity>(de => insertedEntity = de);
O zaman aşağıdaki gibi bir şeyi test edebilirsiniz
Assert.AreEqual("test", insertedEntity.Description, "Wrong Description");
It.Is<T>in a kullanmak daha temiz olabilir Mock.Verify. Ama +1 çünkü bahse girerim bir örnekten en iyi şekilde çalışacak birçok insan vardır.
CallbackMoq'da iki tür vardır . Çağrı dönmeden önce biri olur; diğeri çağrı döndükten sonra gerçekleşir.
var message = "";
mock.Setup(foo => foo.Execute(arg1: "ping", arg2: "pong"))
.Callback((x, y) =>
{
message = "Rally on!";
Console.WriteLine($"args before returns {x} {y}");
})
.Returns(message) // Rally on!
.Callback((x, y) =>
{
message = "Rally over!";
Console.WriteLine("arg after returns {x} {y}");
});
Her iki geri aramada da şunları yapabiliriz:
Callbackbasitçe, sahte yöntemlerden birine çağrı yapıldığında istediğiniz herhangi bir özel kodu yürütmek için bir araçtır. İşte basit bir örnek:
public interface IFoo
{
int Bar(bool b);
}
var mock = new Mock<IFoo>();
mock.Setup(mc => mc.Bar(It.IsAny<bool>()))
.Callback<bool>(b => Console.WriteLine("Bar called with: " + b))
.Returns(42);
var ret = mock.Object.Bar(true);
Console.WriteLine("Result: " + ret);
// output:
// Bar called with: True
// Result: 42
Geçenlerde bunun için ilginç bir kullanım durumuyla karşılaştım. Varsayalım, taklidinize bazı çağrılar beklediğinizi, ancak aynı anda oluyorlar. Yani onların hangi sırayla aranacağını bilmenin bir yolu yok, ancak gerçekleşmesini beklediğiniz aramaların gerçekleştiğini bilmek istiyorsunuz (sıraya bakılmaksızın). Bunun gibi bir şey yapabilirsiniz:
var cq = new ConcurrentQueue<bool>();
mock.Setup(f => f.Bar(It.IsAny<bool>())).Callback<bool>(cq.Enqueue);
Parallel.Invoke(() => mock.Object.Bar(true), () => mock.Object.Bar(false));
Console.WriteLine("Invocations: " + String.Join(", ", cq));
// output:
// Invocations: True, False
BTW, yanıltıcı "önce Returns" ve "sonra Returns" ayrımı ile karıştırılmaz. Bu yalnızca, özel kodunuzun Returnsdeğerlendirildikten sonra mı yoksa daha önce mi çalışacağına ilişkin teknik bir ayrımdır . Arayanın gözünde, her ikisi de değer dönmeden önce çalışır. Nitekim, yöntem void-geri dönüyorsa , arayamazsınız bile Returnsve yine de aynı şekilde çalışır. Daha fazla bilgi için https://stackoverflow.com/a/28727099/67824 adresine bakın .
Buradaki diğer iyi cevapların yanı sıra, bir istisna atmadan önce mantığı gerçekleştirmek için kullandım. Örneğin, daha sonra doğrulama için bir yönteme iletilen tüm nesneleri depolamam ve bu yöntemin (bazı test durumlarında) bir istisna atması gerekiyordu. Arama .Throws(...)üzerinde Mock.Setup(...)geçersiz kılar Callback()eylem ve asla bunu çağırır. Bununla birlikte, Geri Arama içinde bir istisna atarak, geri aramanın sunduğu tüm iyi şeyleri yine de yapabilir ve yine de bir istisna atabilirsiniz.