Конкретные вопросы о модульном тестировании приложений Service Fabric с использованием Mocks

Dec 17 2020

Этот вопрос является продолжением: Написание модульных тестов для класса приложения Service Fabric.

Мое определение приложения относится к типу - упрощенному для решения самых основных проблем, с которыми я сталкиваюсь:

namespace SearchService
{
    internal sealed class SearchServiceClass : StatelessService
    {
        //variables defined followed by constructor
        private string jsonStr;
        public SearchServiceClass(StatelessServiceContext context)
            : base(context)
        {
            try
            {
                var dataPackage = Context.CodePackageActivationContext
                .GetDataPackageObject("Data");
                jsonStr = File.ReadAllText(dataPackage.Path + @"\data.json");
            }
            catch
            {
                //exception handling code
                throw;
            }
        }
        
        public bool IsDataJsonLoaded
        {
            get
            {
                return !(jsonStr == null);
            }
        }
    }
}

А тестовый класс выглядит так:

namespace SearchService.Tests
{
    [TestClass]
    public class SearchServiceClassTest
    {
        [TestMethod]
        public void SearchServiceClassConstructor()
        {
           var searchServiceClass = new SearchServiceClass(MockStatelessServiceContextFactory.Default);
           Assert.IsTrue(searchServiceClass.IsDataJsonLoaded);
        }
    }
}

Исключение, которое я получаю, заключается в том, что «System.NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта », которое возникает из-за того, что для «dataPackage.Path» не установлено допустимое значение в «var dataPackage = Context. .CodePackageActivationContext.GetDataPackageObject ("Данные"); " линия.

Как воспроизвести CodePackageActivationContext с помощью макета? «Данные» здесь относятся к DataPackage, который представляет собой папку с именем «Данные» и находится с кодом для SearchServiceClass.

Ответы

1 singhh-msft Dec 17 2020 at 17:31

Вы можете использовать приведенный ниже фрагмент кода, чтобы имитировать строку:

var codePackageActivationContext = new Mock<ICodePackageActivationContext>();

Для получения дополнительной информации ознакомьтесь с этой статьей: Как использовать платформу Moq для модульного тестирования структур служб Azure?

Для запроса ниже:

Еще кое-что, что я не совсем понимаю, - это переменные и члены, создаваемые в классе, но до вызова конструктора. Например, "частная строка jsonStr;" Строка, похоже, выполняется без суеты в модульном тесте, хотя я вызываю только конструктор в модульном тесте и "частную строку jsonStr;" находится вне конструктора. То же самое будет применяться ко всем переменным, созданным вне конструктора?

Здесь речь идет о простом коде C #: в строке private string jsonStr;определяется jsonStr. Но, прежде чем ссылаться на него, вы должны инициализировать его, иначе он выдаст ошибку нулевой ссылки, которую вы делаете в своем конструкторе.