c# - 单元测试 SQLite 存储库生成“无此类表”错误

标签 c# .net moq repository-pattern

我最近为 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

我已经搞砸了几个小时了,似乎找不到问题所在,任何帮助将不胜感激。我认为模拟存储库可以解决此类问题。

最佳答案

这里的问题是您正在尝试在单元测试的上下文中使用真实的数据库。一种可能的解决方案是引入额外的抽象级别并将存储库与上下文(数据库)分开。这可以使您能够正确模拟依赖项,例如

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);
    }

    ...
}

然后将这个注入(inject)到存储库中...

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);
}

关于c# - 单元测试 SQLite 存储库生成“无此类表”错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56823628/

相关文章:

c# - 如何在调试时使用 ToString 以外的委托(delegate)来显示对象的值?

c# - XML 到 Excel (2007) 使用 Windows XP 和 C#.Net 的想法

c# - 发送多个 Ping 而不等待回复 Windows C#

c# - SOAP 错误 : "Server was unable to process request" "Object reference not set to an instance of an object"

c# - Winforms 如何绑定(bind)到 List<long> DatagridView 并使其正确显示

c# - 模拟 Action<T> 以根据参数返回值

entity-framework-4 - 在 Entity Framework 4 中使用 Moq

c# - 使用 PostSharp 将属性应用于界面

c# - iFrame IE8 使用 jQuery ColorBox

asp.net - 尝试模拟依赖项并向 IoC 容器注册时出现 System.InvalidOperationException