Модульное тестирование SQLite Репозиторий генерирует нет такой ошибки таблицы - PullRequest
2 голосов
/ 30 июня 2019

Я недавно создал приложение для викторины для Xamarin.Android и хочу провести некоторое модульное тестирование в общей библиотеке.

Я использую шаблон репозитория со следующими файлами.

SQLiteMyAppRepository.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SQLite;

namespace MyApp.DataLayer
{
    public class MyAppRepository : IMyAppRepository
    {
        public static string DatabaseName = "MyApp.sqlite";

        private SQLiteConnection _dbConnection;

        public MyAppRepository()
        {
            string docFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            string dbFilePath = Path.Combine(docFolder, DatabaseName);
            _dbConnection = new SQLiteConnection(dbFilePath);
        }

Затем я создал новый проект для проверки некоторых из этих элементов.

Основная проблема, с которой я сталкиваюсь, заключается в том, что при попытке запустить тест яполучаю следующее исключение:

MyApp.Tests.RepositoryTests.AddQuestion threw 
exception: 
SQLite.SQLiteException: no such table: Questions

Я уже несколько часов с этим возиться и не могу понять, что не так, любая помощь будет оценена.Я думал, что Mocking репозитория обойдет любые проблемы, подобные этой.

1 Ответ

3 голосов
/ 30 июня 2019

Проблема здесь в том, что вы пытаетесь использовать реальную базу данных в контексте модульных тестов.Одним из возможных решений может быть введение дополнительного уровня абстракции и отделение хранилища от контекста (базы данных).Это может позволить вам правильно смоделировать зависимости, например

public interface IMyAppContext
{
    IList<Question> GetAllQuestions();
    int AddQuestion(Question question);
    int UpdateQuestion(Question question);
    int DeleteQuestion(Question question);
}

, где реализация может выглядеть примерно так:

public class MyAppContext : IMyAppContext
{
    private readonly string _databaseName = "MyApp.sqlite";
    private readonly SQLiteConnection _dbConnection;

    public MyAppContext()
    {
        string docFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        string dbFilePath = Path.Combine(docFolder, DatabaseName);
        _dbConnection = new SQLiteConnection(dbFilePath);
    }

    public int AddQuestion(Question question)
    {
        return _dbConnection.Insert(question);
    }

    ...
}

, а затем внедрить эту в хранилище ...

public class MyAppRepository : IMyAppRepository
{
    private readonly IMyAppContext _context;

    public MyAppRepository(IMyAppContext context)
    {
        _context = context;
    }

    public int AddQuestion(Question question)
    {
        return _context.Insert(question);
    }

    ...
}

Теперь, после того, как вы выполните эту настройку модульного теста, должно быть, например,

[TestMethod]
public void AddQuestion()
{
    // Arrange
    var contextMock = new Mock<IMyAppContext>();
    contextMock.Setup(r => r.AddQuestion(It.IsAny<Question>())).Returns(1);
    var sut = new SqLiteAbcdRepository(contextMock.Object);

    // Act
    var id = sut.AddQuestion(new Question());

    // Assert
    Assert.AreEqual(1, id);
}
...