J'ai la classe suivante:

    public class UkFileHandler: FileHandler<UkFileHandler.FileMapper>
    {
        public class FileMapper : LookUpFieldDefinition
        {
            public int Name => 1;
            public int Address1 => 4;
            public int Address2 => 5;
        }

        public UkFileHandler(ILoggerFactory loggerFactory, IRecordParser recordParser, 
            IUnzipper unzipper, IFileStore fileStore, IRecordWriter writer) 
            : base(recordParser, unzipper, fileStore, writer)
        {
            Logger = loggerFactory.Create<UkFileHandler>();
        }

        protected override ILogger Logger { get; }

J'essaie de me moquer de cela dans mon test unitaire, avec ma tentative comme suit:

  [Test]
        public void Test()
        {
            var mockLoggerFactory = new Mock<ILoggerFactory>();
            var mockedILogger = new Mock<ILogger>();
            mockLoggerFactory.Setup(lf=> lf.Create<UkFileHandler>()).Returns(mockedILogger.Object);

            var mockUnzipper = new Mock<IUnzipper>();
            var mockFileStore = new Mock<IFileStore>();
            var mockFileWriter = new Mock<IRecordWriter>();

            var mockFileHandler = new Mock<UkFileHandler>
                                    (mockLoggerFactory.Object, new RecordParser(mockLoggerFactory.Object),
                                    mockUnzipper.Object, mockFileStore.Object, mockFileWriter.Object);
           


            // commented out code which calls method 

            Assert.IsNotNull(result);
        }

J'utilise un ILoggerFactory personnalisé qui ressemble à ceci:

 public interface ILoggerFactory
    { 
        ILogger Create<T>();
    }
}

Mon problème est que lors de l'exécution de mon test, l'instance Logger est Null. Je ne peux pas déterminer où j'ai manqué quelque chose ici - est-ce que quelqu'un peut m'aider?

0
Jordan1993 2 sept. 2020 à 11:47

2 réponses

Meilleure réponse

Le problème est le:

protected override ILogger Logger { get; }

Dans votre hiérarchie, la propriété Logger est virtuelle ou abstraite. Mais il existe une solution simple. Convertissez simplement ce getter en propriété complète dans UkFileHandler. Comme ça:

public class UkFileHandler: FileHandler<UkFileHandler.FileMapper>
{
    private readonly ILogger logger;
    
    public class FileMapper : LookUpFieldDefinition
    {
        public int Name => 1;
        public int Address1 => 4;
        public int Address2 => 5;
    }

    public UkFileHandler(ILoggerFactory loggerFactory, IRecordParser recordParser, 
        IUnzipper unzipper, IFileStore fileStore, IRecordWriter writer) 
        : base(recordParser, unzipper, fileStore, writer)
    {
        logger = loggerFactory.Create<UkFileHandler>();
    }

    protected override ILogger Logger => logger;
}
0
Koray Elbek 2 sept. 2020 à 13:14

La première question serait: UkFileHandler est-il le SUT? Si c'est le cas, vous ne vous en moqueriez normalement pas.

La raison pour laquelle il est nul est que la propriété Logger est virtuelle ou abstraite. Vous le remplacez dans UkFileHandler, donc quelque part dans votre hiérarchie d'héritage, vous l'aurez marqué comme virtuel ou abstrait. Une fois que vous avez fait cela, Moq est capable de le remplacer par proxy et de l'initialiser comme valeur par défaut (null), même si vous la définissez dans votre constructeur.

Deux façons de le résoudre.

Étant donné que vous vous moquez d'une implémentation, mockFileHandler.CallBase = true; permettra à tout ce qui n'est pas explicitement configuré de fonctionner selon l'implémentation.

L'autre façon serait de configurer la propriété Logger. Comme il est protégé, vous devez faire quelque chose comme ce qui suit:

mockFileHandler.Protected().Setup<ILogger>("Logger").Returns(mockedILogger.Object);
0
rgvlee 2 sept. 2020 à 13:04