J'ai l'impression de manquer quelque chose de vraiment évident ici. J'ai des classes qui nécessitent l'injection d'options à l'aide du modèle .Net Core IOptions (?). Quand je vais au test unitaire de cette classe, je veux me moquer de différentes versions des options pour valider la fonctionnalité de la classe. Est-ce que quelqu'un sait comment simuler / instancier / remplir correctement les IOptions en dehors de la classe Startup?
Voici quelques exemples des classes avec lesquelles je travaille:
Modèle de paramètres / options
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; }
}
}
Classe à tester qui utilise les paramètres:
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()
{
}
}
}
Test unitaire dans un assembly différent des autres classes:
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>
vous n'avez qu'à vous moquerValue
pour rendre le cours que vous désirezRéponses:
Vous devez créer et remplir manuellement un
IOptions<SampleOptions>
objet. Vous pouvez le faire via laMicrosoft.Extensions.Options.Options
classe helper. Par exemple:Vous pouvez simplifier un peu cela pour:
De toute évidence, ce n'est pas très utile en l'état. Vous devrez créer et remplir un objet SampleOptions et le transmettre à la méthode Create.
la source
new OptionsWrapper<SampleOptions>(new SampleOptions());
partoutSi vous avez l'intention d'utiliser le Mocking Framework comme indiqué par @TSeng dans le commentaire, vous devez ajouter la dépendance suivante dans votre fichier project.json.
Une fois la dépendance restaurée, l'utilisation du framework MOQ est aussi simple que de créer une instance de la classe SampleOptions, puis, comme mentionné, de l'affecter à Value.
Voici un aperçu du code à quoi cela ressemblerait.
Une fois la maquette configurée, vous pouvez maintenant transmettre l'objet maquette au constructeur en tant que
HTH.
Pour info, j'ai un référentiel git qui décrit ces 2 approches sur Github / patvin80
la source
Vous pouvez éviter d'utiliser MOQ du tout. Utilisez dans votre fichier de configuration de tests .json. Un fichier pour de nombreux fichiers de classe de test. Ce sera bien d'utiliser
ConfigurationBuilder
dans ce cas.Exemple de appsetting.json
Exemple de classe de mappage des paramètres:
Exemple de service nécessaire pour tester:
Classe de test NUnit:
la source
Classe donnée
Person
qui dépend de cePersonSettings
qui suit:IOptions<PersonSettings>
peuvent être moqués etPerson
peuvent être testés comme suit:Pour injecter
IOptions<PersonSettings>
dansPerson
au lieu de le passer explicitement au ctor, utilisez ce code:la source
Vous pouvez toujours créer vos options via Options.Create () et utiliser simplement AutoMocker.Use (options) avant de créer l'instance simulée du référentiel que vous testez. L'utilisation d'AutoMocker.CreateInstance <> () facilite la création d'instances sans passer manuellement les paramètres
J'ai un peu changé votre SampleRepo afin de pouvoir reproduire le comportement que je pense que vous souhaitez obtenir.
la source
Voici un autre moyen simple qui n'a pas besoin de Mock, mais utilise à la place le OptionsWrapper:
la source
Pour mes tests système et d'intégration, je préfère avoir une copie / un lien de mon fichier de configuration dans le projet de test. Et puis j'utilise ConfigurationBuilder pour obtenir les options.
De cette façon, je peux utiliser la configuration partout dans mon TestProject. Pour les tests unitaires, je préfère utiliser MOQ comme décrit par patvin80.
la source
D'accord avec Aleha, l'utilisation d'un fichier de configuration testSettings.json est probablement meilleure. Et puis, au lieu d'injecter l'IOption, vous pouvez simplement injecter les vrais SampleOptions dans votre constructeur de classe, lorsque vous testez la classe unitaire, vous pouvez faire ce qui suit dans un fixture ou à nouveau simplement dans le constructeur de la classe de test:
la source