Moq kullanarak ve baktım Callback
ama 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 Callback
ama 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 ...
Setup
Yaptığınız her alay yöntemi için, aşağıdaki gibi şeyler belirtebilirsiniz:
.Callback
Mekanizma "Ş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 .
Callback
dö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 ( Returns
sı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.
Callback
Moq'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:
Callback
basitç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 Returns
değ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 Returns
ve 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.