Saya merasa seperti kehilangan sesuatu yang sangat jelas di sini. Saya memiliki kelas yang memerlukan injeksi opsi menggunakan pola Net. IOptions (?). Ketika saya pergi ke unit test kelas itu, saya ingin mengejek berbagai versi opsi untuk memvalidasi fungsionalitas kelas. Adakah yang tahu bagaimana cara mengejek / instantiate / mengisi IOptions dengan benar di luar kelas Startup?
Berikut adalah beberapa contoh kelas yang saya kerjakan:
Pengaturan / Opsi Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace OptionsSample.Models
{
public class SampleOptions
{
public string FirstSetting { get; set; }
public int SecondSetting { get; set; }
}
}
Kelas yang akan diuji yang menggunakan Pengaturan:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OptionsSample.Models
using System.Net.Http;
using Microsoft.Extensions.Options;
using System.IO;
using Microsoft.AspNetCore.Http;
using System.Xml.Linq;
using Newtonsoft.Json;
using System.Dynamic;
using Microsoft.Extensions.Logging;
namespace OptionsSample.Repositories
{
public class SampleRepo : ISampleRepo
{
private SampleOptions _options;
private ILogger<AzureStorageQueuePassthru> _logger;
public SampleRepo(IOptions<SampleOptions> options)
{
_options = options.Value;
}
public async Task Get()
{
}
}
}
Tes unit dalam majelis berbeda dari kelas lain:
using OptionsSample.Repositories;
using OptionsSample.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
namespace OptionsSample.Repositories.Tests
{
public class SampleRepoTests
{
private IOptions<SampleOptions> _options;
private SampleRepo _sampleRepo;
public SampleRepoTests()
{
//Not sure how to populate IOptions<SampleOptions> here
_options = options;
_sampleRepo = new SampleRepo(_options);
}
}
}
IOptions<T>
kamu hanya perlu mengejekValue
untuk mengembalikan kelas yang kamu inginkanJawaban:
Anda perlu membuat dan mengisi
IOptions<SampleOptions>
objek secara manual . Anda dapat melakukannya melaluiMicrosoft.Extensions.Options.Options
kelas pembantu. Sebagai contoh:Anda dapat menyederhanakannya menjadi:
Jelas ini tidak terlalu berguna. Anda harus benar-benar membuat dan mengisi objek SampleOptions dan meneruskannya ke metode Buat.
sumber
new OptionsWrapper<SampleOptions>(new SampleOptions());
manaJika Anda bermaksud untuk menggunakan Mocking Framework seperti yang ditunjukkan oleh @TSeng dalam komentar, Anda perlu menambahkan ketergantungan berikut di file project.json Anda.
Setelah dependensi dipulihkan, menggunakan kerangka kerja MOQ semudah membuat instance kelas SampleOptions dan kemudian seperti yang disebutkan, tetapkan nilai tersebut ke Value.
Berikut ini adalah garis besar kode yang akan terlihat.
Setelah tiruan diatur, Anda sekarang dapat meneruskan objek tiruan ke konstruktor sebagai
HTH.
FYI Saya memiliki repositori git yang menguraikan 2 pendekatan ini pada Github / patvin80
sumber
Anda dapat menghindari penggunaan MOQ sama sekali. Gunakan dalam file konfigurasi .json pengujian Anda. Satu file untuk banyak file kelas uji. Akan baik-baik saja untuk digunakan
ConfigurationBuilder
dalam kasus ini.Contoh appsetting.json
Contoh kelas pemetaan pengaturan:
Contoh layanan yang diperlukan untuk menguji:
Kelas tes NUnit:
sumber
Kelas
Person
yang diberikan tergantung padaPersonSettings
sebagai berikut:IOptions<PersonSettings>
dapat diejek danPerson
dapat diuji sebagai berikut:Untuk menyuntikkan
IOptions<PersonSettings>
ke dalamPerson
bukan lewat secara eksplisit untuk ctor, gunakan kode ini:sumber
Anda selalu dapat membuat opsi melalui Options.Create () dan daripada hanya menggunakan AutoMocker.Use (options) sebelum benar-benar membuat instance tiruan dari repositori yang Anda uji. Menggunakan AutoMocker.CreateInstance <> () membuatnya lebih mudah untuk membuat instance tanpa melewati parameter secara manual
Saya telah mengubah Anda sedikit SampleRepo agar dapat mereproduksi perilaku yang saya pikir ingin Anda capai.
sumber
Berikut cara mudah lain yang tidak perlu Mock, tetapi gunakan OptionsWrapper:
sumber
Untuk pengujian sistem dan integrasi, saya lebih suka memiliki salinan / tautan file konfigurasi saya di dalam proyek pengujian. Dan kemudian saya menggunakan ConfigurationBuilder untuk mendapatkan opsi.
Dengan cara ini saya dapat menggunakan konfigurasi di mana saja di dalam TestProject saya. Untuk pengujian unit, saya lebih suka menggunakan MOQ seperti yang dijelaskan oleh patvin80.
sumber
Setuju dengan Aleha yang menggunakan file konfigurasi testSettings.json mungkin lebih baik. Dan alih-alih menyuntikkan IOption Anda cukup menyuntikkan SampleOptions nyata di konstruktor kelas Anda, ketika unit menguji kelas, Anda dapat melakukan hal berikut di fixture atau lagi hanya di konstruktor kelas tes:
sumber