Pertanyaan Bisakah Anda membantu saya memahami Callback Moq?


Menggunakan Moq dan melihat Callback tetapi saya belum dapat menemukan contoh sederhana untuk memahami cara menggunakannya.

Apakah Anda memiliki potongan kerja kecil yang dengan jelas menjelaskan bagaimana dan kapan menggunakannya?


76
2018-05-14 09:44


asal


Jawaban:


Sulit untuk dikalahkan https://github.com/Moq/moq4/wiki/Quickstart

Jika itu tidak cukup jelas, saya akan menyebut itu bug dokumen ...

EDIT: Menanggapi klarifikasi Anda ...

Untuk setiap metode yang diejek Setup Anda melakukan, Anda bisa menunjukkan hal-hal seperti:

  • kendala pada input
  • nilai untuk / cara di mana nilai pengembalian (jika ada) akan diturunkan

Itu .Callback Mekanisme mengatakan "Saya tidak bisa menggambarkannya sekarang, tetapi ketika sebuah panggilan yang berbentuk seperti ini terjadi, panggil saya kembali dan saya akan melakukan apa yang perlu dilakukan". Sebagai bagian dari rantai panggilan fasih yang sama, Anda dapat mengontrol hasilnya untuk kembali (jika ada) melalui .Returns". Dalam contoh QS, contohnya adalah bahwa mereka membuat nilai yang dikembalikan meningkat setiap waktu.

Secara umum, Anda tidak akan memerlukan mekanisme seperti ini sangat sering (xUnit Test Patterns memiliki istilah untuk antipatterns dari Ilk Conditional Logic In Tests), dan jika ada cara yang lebih sederhana atau built-in untuk menetapkan apa yang Anda butuhkan, itu harus digunakan dalam preferensi.

Bagian 3 dari 4 dalam seri Moq Justin Etheredge menutupinya, dan ada contoh lain dari callback di sini


65
2018-05-14 14:06



Berikut ini contoh penggunaan callback untuk menguji entitas yang dikirim ke Layanan Data yang menangani insert.

var mock = new Mock<IDataService>();
DataEntity insertedEntity = null;

mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1) 
           .Callback((DataEntity de) => insertedEntity = de);

Sintaks metode generik alternatif:

mock.Setup(x => x.Insert(It.IsAny<DataEntity>())).Returns(1) 
           .Callback<DataEntity>(de => insertedEntity = de);

Maka Anda dapat menguji sesuatu seperti

Assert.AreEqual("test", insertedEntity.Description, "Wrong Description");

46
2018-01-30 21:21



Ada dua jenis Callback dalam moq. Satu terjadi sebelum panggilan kembali; yang lain terjadi setelah panggilan kembali.

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}");
    });

Pada kedua callback, kita dapat:

  1. periksa argumen metode
  2. menangkap arguemnts metode
  3. mengubah keadaan kontekstual

6
2018-01-26 01:10



Callback hanyalah sarana untuk mengeksekusi kode kustom yang Anda inginkan ketika panggilan dilakukan ke salah satu metode tiruan. Inilah contoh sederhana:

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

Saya baru-baru ini menggunakan kasus yang menarik untuk itu. Misalkan Anda mengharapkan panggilan ke mock Anda, tetapi itu terjadi secara bersamaan. Jadi Anda tidak memiliki cara untuk mengetahui urutan di mana mereka akan dipanggil, tetapi Anda ingin tahu panggilan yang Anda harapkan terjadi (terlepas dari pesanan). Anda dapat melakukan sesuatu seperti ini:

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 tidak bingung dengan menyesatkan "sebelumnya Returns" dan kemudian Returns"Perbedaan. Ini hanyalah perbedaan teknis apakah kode kustom Anda akan berjalan setelahnya Returns telah dievaluasi atau sebelumnya. Di mata si penelepon, keduanya akan berjalan sebelum nilainya dikembalikan. Sesungguhnya, jika metodenya benar void-mengembalikan Anda bahkan tidak bisa menelepon Returns namun cara kerjanya sama. Untuk informasi lebih lanjut, lihat https://stackoverflow.com/a/28727099/67824.


2
2017-08-10 11:10



Di atas jawaban baik lainnya di sini, saya telah menggunakannya untuk melakukan logika sebelum melempar pengecualian. Misalnya, saya perlu menyimpan semua objek yang diteruskan ke metode untuk verifikasi nanti, dan metode tersebut (dalam beberapa kasus pengujian) diperlukan untuk melempar pengecualian. Panggilan .Throws(...)di Mock.Setup(...) menimpa Callback() tindakan dan tidak pernah menyebutnya. Namun, dengan membuang pengecualian dalam Callback, Anda masih dapat melakukan semua hal baik yang harus ditawarkan callback, dan masih membuang pengecualian.


1
2018-01-10 03:03