Autofixture: Membangun instance yang disesuaikan gagal pada referensi melingkar

Dibuat pada 13 Jan 2018  ·  5Komentar  ·  Sumber: AutoFixture/AutoFixture

    [TestFixture]
    public class TestAutoFixture4
    {
        [Test]
        [AutoMoqData]
        public void CreatingAnDummyObjectShouldNotThrow(IFixture fixture)
        {
            fixture.Invoking(x => x.Create<DummyObject>()).ShouldNotThrow();
        }

        [Test]
        [AutoMoqData]
        public void BuildingAnDummyObjectShouldNotThrow(IFixture fixture)
        {
            fixture.Invoking(x => x.Build<DummyObject>().Create()).ShouldNotThrow();
        }
    }

    public class DummyObject
    {
        public Guid Id { get; set; }
        public DummyObject CircularRef { get; set; }
    }

    public class AutoMoqDataAttribute : AutoDataAttribute
    {
        public AutoMoqDataAttribute()
            : base(new Fixture()
                 .Customize(
                    new DummyCustomization()
                ))
        { }
    }

    public class DummyCustomization : ICustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.Customize<DummyObject>(c =>
                c.Without(x => x.CircularRef)
            );
        }
    }

Baru saja memperbarui AutoFixture dari 3.50.6 ke 4.0.0.

Kode di atas bekerja dengan sempurna pada 3.50.6, tetapi hanya pengujian pertama (menggunakan fixture.Create) yang lolos menggunakan 4.0.0 (.NET 4.6.2, NUnit3.7.1, FluentAssertions 4.19.4).

Pengujian menggunakan fixture.Build gagal, bahkan jika kustomisasi yang disuntikkan menentukan untuk tidak menyelesaikan referensi melingkar.

Apakah saya melewatkan sesuatu di changelog atau itu bug?

Terima kasih sebelumnya :)

question

Komentar yang paling membantu

Apakah menurut Anda pendekatan Omitter dapat menyelesaikan masalah? Saya tidak tahu kelas ini dan pasti akan mencobanya.

Jika Anda menulis ulang kustomisasi Anda sebagai berikut, semua tes akan mulai lulus:

c# public class DummyCustomization : ICustomization { public void Customize(IFixture fixture) { // Don't populate the DummyObject.CircularRef property. fixture.Customizations.Add( new Omitter( new EqualRequestSpecification( typeof(DummyObject).GetProperty(nameof(DummyObject.CircularRef))))); } }

Oleh karena itu, ya, itu harus memperbaiki masalah Anda Juga pendekatan ini tidak terlihat terlalu rumit, jadi harus dapat diterima.

Harap beri tahu saya jika Anda memiliki pertanyaan lebih lanjut tentang pertanyaan Anda.

Semua 5 komentar

@Dev-I-Ant Terima kasih telah memposting masalah ini di sini dan untuk deskripsi yang begitu mendetail 👍

Nah, perilaku ini adalah hasil dari perubahan yang diterapkan di #781. Saya telah memperbaiki masalah ketika satu penyesuaian dapat memengaruhi penyesuaian lainnya. Itu terjadi bahkan jika Anda memiliki dua penyesuaian berikutnya untuk jenis yang sama - yang sebelumnya akan sepenuhnya diabaikan.

Saat Anda menggunakan Build<T>() API, Anda sebenarnya membuat penyesuaian sementara untuk tipe DummyObject . Itu berarti bahwa semua penyesuaian sebelumnya (diterapkan melalui Customize<DummyObject>() API) diabaikan dan tidak berpartisipasi. Itu sebabnya Anda kembali melihat kesalahan tentang ketergantungan melingkar.

Isolasi semacam ini diperlukan, jika tidak, masalah yang sangat aneh dapat terjadi (lihat masalah yang dirujuk dalam PR yang disebutkan di atas). Oleh karena itu, untuk menjaga hal-hal sederhana, saya akan mengatakan bahwa perilaku yang diamati bukanlah bug, melainkan kekhususan desain yang kita miliki saat ini.


Untuk mengurangi masalah yang Anda amati, pada dasarnya saya melihat dua cara.

Solusi 1: Tambahkan Omitter untuk properti

Kami sudah memiliki pertanyaan serupa, sehingga Anda dapat menggunakan kembali pendekatan yang disarankan di sini atau mengubahnya agar lebih sesuai dengan kebutuhan Anda. Jelas, jika itu adalah skenario umum dalam proyek Anda, Anda dapat membuat metode ekstensi untuk mencapai tugas dengan lebih mudah.

Solusi 2: Gunakan API Create<T>() sebagai gantinya

Dalam sampel Anda, tidak perlu menggunakan Build<> API. Tentu saja, mungkin Anda memberikan contoh yang disederhanakan dan sebenarnya Anda membutuhkan API itu. Namun, saya memutuskan untuk memberi Anda opsi ini untuk berjaga-jaga

Beri tahu saya apakah jawaban saya membantu menjelaskan masalah ini

@zvirja Terima kasih atas wawasan Anda, ini membuat segalanya lebih jelas.

Saya sudah membaca banyak tentang fakta bahwa menumpuk kustomisasi pada jenis yang sama tidak mungkin (bahkan jika membuat frustrasi), dan perubahan ini pasti akan memberi saya beberapa masalah, tetapi saya mengerti mengapa Anda harus mengubah sesuatu.

Kasus penggunaan saya sedang menguji aplikasi menggunakan grafik besar objek yang banyak referensi melingkar; pola (anti-?) khas di mana orang tua memegang daftar anak-anak yang pada gilirannya merujuk orang tua mereka.

Saya ingin mengubah model tetapi itu tidak mungkin, setidaknya untuk saat ini.

Jadi cukup membuat objek menggunakan fixture.Create bukanlah pilihan dan kami biasanya membangunnya dengan memanggil OmitAllProperties tepat setelahnya, yang membatasi kekuatan AF.

Jadi saya biasa membuat beberapa penyesuaian yang menanganinya untuk saya, menghilangkan referensi melingkar (kemudian para pengembang hanya perlu membangun objek mereka tanpa harus peduli apakah ada referensi melingkar atau tidak, dan dapat menyesuaikannya lebih lanjut menggunakan Dengan, Tanpa dan sebagainya). Tapi perubahan ini menghancurkan semua ini.
Apakah menurut Anda pendekatan Omitter dapat menyelesaikan masalah? Saya tidak tahu kelas ini dan pasti akan mencobanya.

Sekali lagi terima kasih, dan tolong beri tahu saya jika Anda pikir Anda dapat menambahkan sesuatu ke refleksi saya.

Apakah menurut Anda pendekatan Omitter dapat menyelesaikan masalah? Saya tidak tahu kelas ini dan pasti akan mencobanya.

Jika Anda menulis ulang kustomisasi Anda sebagai berikut, semua tes akan mulai lulus:

c# public class DummyCustomization : ICustomization { public void Customize(IFixture fixture) { // Don't populate the DummyObject.CircularRef property. fixture.Customizations.Add( new Omitter( new EqualRequestSpecification( typeof(DummyObject).GetProperty(nameof(DummyObject.CircularRef))))); } }

Oleh karena itu, ya, itu harus memperbaiki masalah Anda Juga pendekatan ini tidak terlihat terlalu rumit, jadi harus dapat diterima.

Harap beri tahu saya jika Anda memiliki pertanyaan lebih lanjut tentang pertanyaan Anda.

Ini bekerja dengan sempurna. Terima kasih banyak! Saya kira Anda bisa menutup ini kemudian :)

@Dev-I-Ant Luar biasa, terima kasih atas umpan baliknya! :)

Apakah halaman ini membantu?
0 / 5 - 0 peringkat