web-dev-qa-db-fra.com

Comment configurer Mock of IConfigurationRoot pour renvoyer la valeur

J'ai utilisé IConfigurationRoute pour accéder à un répertoire comme celui-ci.

if (type == "error") directory = _config.GetValue<string>("Directories:SomeDirectory");

_config est IConfigurationRoot injecté dans le constructeur.

J'ai essayé la façon suivante de le railler.

        var mockConfigurationRoot = new Mock<IConfigurationRoot>();
        mockConfigurationRoot.Setup(c => c.GetValue<string>("Directories: SomeDirectory"))
            .Returns("SomeDirectory")
            .Verifiable();
        var config = mockConfigurationRoot.Object;

Le problème est lors de l'exécution du test Xunit lève l'exception en disant

"System.NotSupportedException: l'expression fait référence à une méthode qui n'appartient pas à l'objet simulé"

Comment puis-je résoudre ce problème?

13
Virodh

Je l'ai fait en utilisant la méthode SetupGet comme suit. Cela fonctionne pour moi, j'espère que cela aide.

_configurationRoot = new Mock<IConfigurationRoot>();
_configurationRoot.SetupGet(x => x[It.IsAny<string>()]).Returns("the string you want to return");
21
user3130628
  1. Copiez appSettings.json dans le répertoire racine de votre projet de test et marquez sa propriété en tant que contenu et copiez si elle est plus récente.

  2. var builder = new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
          .AddEnvironmentVariables();
    ConfigurationManager.Configuration = builder.Build();
    
  3. ConfigurationManager est une classe et possède une propriété statique Configuration. De cette façon, l'application entière peut simplement y accéder en tant que ConfigurationManager.Configuration []

8

Je pense que la façon dont vous le feriez serait de créer des méthodes d'extension de proxy moquables et de les utiliser à la place. Les méthodes d'extension locales peuvent remplacer les méthodes externes, vous pouvez donc créer votre propre classe d'extensions:

public static class ConfigurationExtensions
{
    public static IConfigurationProxy Proxy = new ConfigurationProxy();
    public static T GetValue<T>(this IConfigurationRoot config, string key) => Proxy.GetValue<T>(config, key);
}

Ensuite, configurez votre proxy:

public class ConfigurationProxy : IConfigurationProxy
{
    public T GetValue<T>(IConfigurationRoot config, string key) => config.GetValue<T>(key);
}

Maintenant, dans chaque classe où vous souhaitez utiliser des méthodes d'extension modifiables, ajoutez un constructeur statique:

static MyClass()
{
    ConfigurationExtensions.Proxy = new ConfigurationProxy();
}

Ou

static MyClass_Tests()
{
    ConfigurationExtensions.Proxy = Mock.Of<IConfigurationProxy>();
}

Laver, rincer, répéter pour chaque méthode d'extension que vous devez utiliser. Plus d'explications peuvent être trouvées ici: http://blogs.clariusconsulting.net/kzu/how-to-design-a-unit-testable-domain-model-with-entity-framework-code-first/

De plus, au cas où cela serait utile, vous pouvez également vous moquer du getter du dictionnaire:

mockConfigurationRoot.SetupGet(m => m["ConnectionStrings:Repository"]).Returns("bogus");
1
Chris D