如何在带有实体框架4.0的MVC4中使用ViewModel模拟方法

欧文(Erwin Rooijakkers)

我想测试以下方法:

public ActionResult Index()
{
    var transactions = db.Transactions.Include(t => t.User)
                            .GroupBy(t => t.UserId)
                            .Select(group => new TransactionViewModel
                            {
                                User = group.FirstOrDefault().User.FullName,
                                UserId = group.FirstOrDefault().UserId,
                                Total = (group.Sum(t => t.TransactionAmount))
                            });

    // Show lowest balance first
    return View(transactions.ToList());
}

Transaction模型在此处具有的列表Orders,具有的外键User和更多属性,请参见:

public class Transaction
{
    public int TransactionId { get; set; }
    public DateTime Date { get; set; }
    public int UserId { get; set; }
    public List<Order> Orders { get; set; }
    public decimal TransactionAmount { get; set; }
    public virtual User User { get; set; }
}

TransactionViewModel如下外观:

public class TransactionViewModel
{
    public string User { get; set; }
    public int UserId { get; set; }
    public decimal Total { get; set; }
}

并用于计算Total属于用户的不同交易的金额。

为了测试此方法,我在以下安装程序中FakeDbSet使用FakeContext并使用了(两者都可在其他控制器的测试中使用):

[TestClass]
public class TransactionControllerTest
{
    TransactionController trController;

    [TestInitialize]
    public void TransactionControllerTestInitialize()
    {
        // Arrange 
        var memoryTransactionItems = new FakeDbSet<Transaction>
        {
           new Transaction {
               Date = DateTime.Today,
               TransactionAmount = 5.10M,
               UserId = 1,
               Orders = new List<Order>{
                    // Categorie 2 and confirmed
                    new Order { OrderId = 2, 
                                UnitPrice = 2.00M, 
                                Quantity = 1, 
                                Date = DateTime.Today, 
                                IsConfirmed = true, 
                                User = new User { 
                                    Name = "Kees", 
                                    FullName="Kees Piet", 
                                    Email = "[email protected]", 
                                    isAvailable = true, 
                                    UserId = 1 
                                }, 
                                Product = new Product {
                                    Category = new Category {
                                        CategoryId = 2, 
                                        Name = "Categorie2"
                                    }, 
                                    Name = "Testproduct2",
                                    Price = 2.00M,
                                    Visible = true
                                }
                    },
                    // Categorie 2 and confirmed
                    new Order { OrderId = 2, 
                                UnitPrice = 1.00M, 
                                Quantity = 1, 
                                Date = DateTime.Today, 
                                IsConfirmed = true, 
                                User = new User { 
                                    Name = "Jan", 
                                    FullName="Jan Piet", 
                                    Email = "[email protected]", 
                                    isAvailable = true, 
                                    UserId = 2 
                                }, 
                                Product = new Product {
                                    Category = new Category {
                                        CategoryId = 2, 
                                        Name = "Categorie2"
                                    }, 
                                    Name = "Testproduct2",
                                    Price = 3.10M,
                                    Visible = true
                                }
                    }
               }
           }
        };


        // Create mock units of work
        var mockData = new Mock<FakeContext>();
        mockData.Setup(m => m.Transactions).Returns(memoryTransactionItems);

        // Setup controller
        trController = new TransactionController(mockData.Object);
    }

    [TestMethod]
    public void TestTransactionIndex()
    {
        // Invoke
        var viewResult = trController.Index() as ViewResult;
        var transactionsFromView = (IEnumerable<TransactionViewModel>)viewResult.Model;

        // Assert
        Assert.AreEqual(1, transactionsFromView.Count(),
            "The amount of transactions added to the Index View should be 1.");
    }
}

当我运行时,TestTransactionIndex出现以下错误:

测试名称:TestTransactionIndex测试结果:测试失败持续时间:0:00:30.6276475

结果消息:测试方法Tests.Controllers.TransactionControllerTest.TestTransactionIndex引发异常:System.NullReferenceException:对象引用未设置为对象的实例。结果StackTrace:位于lambda_method(Closure,IGrouping 2 ) at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
位于System.Collections.Generic.List 1..ctor(IEnumerable1集合)
位于System.Linq.Enumerable.ToList [TSource](IEnumerable`1源)位于Controllers.TransactionController.Index()

我发现这很奇怪,因为我以正确的方式设置了模拟单元。希望有人能解释我如何正确地将FakeDbSet<Transaction>视图发送给视图而不获取视图NullReferenceException

/编辑根据要求,这里是构造函数TransactionController

private IContext _context;

public TransactionController()
{
    _context = new Context();
}

public TransactionController(IContext context)
{
    _context = context;
}
丹尼尔·JG

索引方法中的查询包括以下行:

db.Transactions.Include(t => t.User)

并且查询Select部分正在使用类中User属性Transaction来填充TransactionViewModelin

User = group.FirstOrDefault().User.FullName,

如果Transaction中的User属性为null,则该行将引发NullReferenceException因此,当您在使用伪造对象的单元测试中执行该查询时,您需要该查询的结果包含一个非null的User属性。

我不确定您的伪造上下文和DbSets如何工作,但是最容易尝试的方法是在您的造假中填充Transactions的User属性memoryTransactionItems

您还可以尝试在下一个代码段中添加伪造的用户dbset(我假设您在EF上下文中有一个Users DbSet):

var memoryUsers = new FakeDbSet<User>
{
    new User{ UserId = 1, ... },
    ...
};

mockData.Setup(m => m.Users).Returns(memoryUsers);

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在带有实体框架4.0的MVC4中使用ViewModel模拟方法

来自分类Dev

如何使用带有剃刀视图的实体框架(.edmx模型)为MVC4或MVC 5创建局部视图?

来自分类Dev

如何在不使用实体框架的情况下在MVC4中执行编辑功能?

来自分类Dev

如何在带有实体框架5的Linq中使用DbGeography.Filter?

来自分类Dev

在MVC4中使用HtmlHelpers

来自分类Dev

如何从带有实体框架的列表中获取以下项目?

来自分类Dev

如何在MVC4中初始化ViewModel

来自分类Dev

如何在现有实体框架中添加新表

来自分类Dev

如何在实体框架中更新表的所有记录?

来自分类Dev

如何在现有实体框架中添加新表

来自分类Dev

如何在不使用ASP.NET MVC4中的实体框架的情况下从数据库检索图像

来自分类Dev

如何在不使用ASP.NET MVC4中的实体框架的情况下从数据库检索图像

来自分类Dev

如何在带有Nestjs框架的neo4j-graphql-js端点中使用拦截器?

来自分类Dev

在MVC4中使用波斯Datetimepicker

来自分类Dev

在视图mvc4中使用Response.Redirect

来自分类Dev

来自实体框架的mvc4中的PieChart

来自分类Dev

如何在MVC4中使用Html.ListBoxFor

来自分类Dev

如何在MVC4中使用href?我被困在那里

来自分类Dev

如何在MVC4中使用FormCollection获得Checkbox的价值

来自分类Dev

如何使用ViewModel在MVC4应用程序中实现IEnumerator

来自分类Dev

无法在使用实体框架的MVC4 Intranet App中以Razor语法使用HtmlHelper

来自分类Dev

如何在没有实体框架的情况下使用Windows身份框架(WIF)

来自分类Dev

使用实体框架6的mvc4中的单个或多个DbContext文件

来自分类Dev

如何在vNext MVC中使用实体框架和OData

来自分类Dev

具有实体框架5和MVC4的Log4net

来自分类Dev

无法在MVC4中使用ViewModel概念从同一视图输入数据并在同一视图中显示数据

来自分类Dev

如何使用带有实体框架代码的Postgresql使用串行字段

来自分类Dev

使用ViewModel和ActionLink时无法在MVC4中应用分页

来自分类Dev

如何使用带有存储过程的实体框架避免超时异常?

Related 相关文章

  1. 1

    如何在带有实体框架4.0的MVC4中使用ViewModel模拟方法

  2. 2

    如何使用带有剃刀视图的实体框架(.edmx模型)为MVC4或MVC 5创建局部视图?

  3. 3

    如何在不使用实体框架的情况下在MVC4中执行编辑功能?

  4. 4

    如何在带有实体框架5的Linq中使用DbGeography.Filter?

  5. 5

    在MVC4中使用HtmlHelpers

  6. 6

    如何从带有实体框架的列表中获取以下项目?

  7. 7

    如何在MVC4中初始化ViewModel

  8. 8

    如何在现有实体框架中添加新表

  9. 9

    如何在实体框架中更新表的所有记录?

  10. 10

    如何在现有实体框架中添加新表

  11. 11

    如何在不使用ASP.NET MVC4中的实体框架的情况下从数据库检索图像

  12. 12

    如何在不使用ASP.NET MVC4中的实体框架的情况下从数据库检索图像

  13. 13

    如何在带有Nestjs框架的neo4j-graphql-js端点中使用拦截器?

  14. 14

    在MVC4中使用波斯Datetimepicker

  15. 15

    在视图mvc4中使用Response.Redirect

  16. 16

    来自实体框架的mvc4中的PieChart

  17. 17

    如何在MVC4中使用Html.ListBoxFor

  18. 18

    如何在MVC4中使用href?我被困在那里

  19. 19

    如何在MVC4中使用FormCollection获得Checkbox的价值

  20. 20

    如何使用ViewModel在MVC4应用程序中实现IEnumerator

  21. 21

    无法在使用实体框架的MVC4 Intranet App中以Razor语法使用HtmlHelper

  22. 22

    如何在没有实体框架的情况下使用Windows身份框架(WIF)

  23. 23

    使用实体框架6的mvc4中的单个或多个DbContext文件

  24. 24

    如何在vNext MVC中使用实体框架和OData

  25. 25

    具有实体框架5和MVC4的Log4net

  26. 26

    无法在MVC4中使用ViewModel概念从同一视图输入数据并在同一视图中显示数据

  27. 27

    如何使用带有实体框架代码的Postgresql使用串行字段

  28. 28

    使用ViewModel和ActionLink时无法在MVC4中应用分页

  29. 29

    如何使用带有存储过程的实体框架避免超时异常?

热门标签

归档