【问题标题】:How to define a Controller context when testing an ActionResult测试 ActionResult 时如何定义 Controller 上下文
【发布时间】:2016-06-12 00:40:09
【问题描述】:

我有一个 ActionResult,它在带有 EntityFramework 和 Epplus 的 MVC 5 项目中始终如一地工作。单击视图上的操作链接会触发此 ActionResult,它将所选模型发送到新的 Excel 文档。

我正在学习在 Visual Studio 2013 中对我的 MVC 代码进行单元测试(使用 Nuget Xunit 包),并认为我将从小处着手,在通过断言 ActionResult 不为空来实现 ActionResult。

测试失败,回复如下:"System.InvalidOperationException : No connection string named 'StudentContext' could be found in the application config file."

我了解错误消息的含义,但我的问题是如何在测试项目中正确定义控制器上下文。我是否遗漏了一些简单明了的东西,比如定义一个上下文变量,还是我完全错误的方式?

这是我用来测试 ActionResult 的代码块。

using StudentProject.Controllers;
using System.Web.Mvc;
using Xunit;

namespace StudentProject.Tests.Controllers
{
    public class StudentRosterControllerTest
    {
        [Fact]
        public void ExportToExcel_IsNotNull()
        {
            // Arrange
            StudentRostersController controller = new StudentRostersController();            
            ActionResult ExcelExport;

            // Act
            ExcelExport = controller.ExportToExcel();

            // Assert
            Assert.NotNull(ExcelExport);
        }
    }
}

这是我正在测试的代码。它是一个自动脚手架控制器,隐藏了自动生成的 crud 方法,显示了要测试的单个方法。

using OfficeOpenXml;
using StudentProject.Models;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;

namespace StudentProject.Controllers
{
    public class StudentRostersController : Controller
    {
        private StudentContext db = new StudentContext();

        // Auto-scaffolded CRUD methods not shown

        // This ActionResult exports the StudentRoster model 
        // to a fresh Excel file.

        public ActionResult ExportToExcel()
        {
            IEnumerable<StudentRoster> query = db.StudentRosters.AsEnumerable();

            using (var excelFile = new ExcelPackage())
            {
                ExcelWorksheet worksheet =
                    excelFile.Workbook.Worksheets.Add("Sheet1");
                worksheet.Cells["A1"].LoadFromCollection(Collection: query, 
                    PrintHeaders: true);

                // Results in file downloaded to user's default 
                // "My Downloads" folder.
                return File(excelFile.GetAsByteArray(),
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",  
               "Export.xlsx");   
            }
        }
    }
}

【问题讨论】:

    标签: c# asp.net-mvc unit-testing tdd xunit


    【解决方案1】:

    System.InvalidOperationException:没有命名的连接字符串 'StudentContext' 可以在应用程序配置文件中找到。”

    确保测试项目的 app.config 文件具有适合您的 EF 的正确连接字符串设置。

    测试项目app.config

    <connectionStrings>
      <add name="StudentContext" connectionString="..." providerName="System.Data.EntityClient" />
    </connectionStrings>
    

    我如何在测试项目中正确定义控制器上下文

    您的测试应该尝试复制运行时环境。提供了测试 SUT 所需的最低要求。

    namespace StudentProject.Tests.Controllers
    {
        public class StudentRosterControllerTest
        {
            [Fact]
            public void ExportToExcel_IsNotNull()
            {
                // Arrange
                StudentRostersController controller = new StudentRostersController();
                controller.ControllerContext = new ControllerContext() {
                    Controller = controller,
                    //...other properties needed for test
                };
    
                // Act
                var actionResult = controller.ExportToExcel();
    
                // Assert
                Assert.NotNull(actionResult);
            }
        }
    }
    

    鉴于您正在连接到您的实际数据库,那么这将被视为更多的集成测试。

    我建议抽象您的数据访问,以便您可以在单元测试中对其进行模拟。

    【讨论】:

    • 它的工作原理是:(1) 使用 Nuget 将 Entity Framework 安装到我的测试项目中,以及 (2) 将复制的连接字符串复制到 app.config 文件中。我上面提出的代码现在可以工作了。
    • 我同意您关于抽象数据访问的建议。我可以使用关键字或搜索词来找到合适的教程吗?
    • 我会说寻找抽象的数据访问层。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2023-01-23
    • 2018-03-09
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多