【问题标题】:MVC4 Unit test NSubstitute Could not find a call to return fromMVC4 单元测试 NSubstitute 找不到返回的调用
【发布时间】:2014-12-04 19:06:26
【问题描述】:

我有一个 MVC4 Web 应用程序,我现在正在单元测试。它对数据库部分使用实体框架。我正在使用 NSubstitute 来模拟数据库。这段代码基本上是从另一个可以正常工作的网站复制和粘贴的,所以我希望我只是错过了一些超级简单的东西。

提前致谢!

SQL 中的应用程序表:

AppID   | ApplicationName
----------------------------
1       | MyCoolApplication
2       | MyOtherApplication

实体创建了应用程序类:

public class Application
{
    public int AppID { get; set; }
    public string ApplicationName { get; set; }
}

单元测试的模拟部分如下所示:

var mockDb = Substitute.For<MyCoolApplicationsEntities>();

var applications = new List<Application>
{
    new Application {AppID = 1, ApplicationName = "MyCoolApplication"},
    new Application {AppID = 2, ApplicationName = "MyOtherApplication"},
};

var mockApplicationSet = Substitute.For<IDbSet<Application>, DbSet<Application>>();
mockApplicationSet.Provider.Returns(applications.AsQueryable().Provider);
mockApplicationSet.Expression.Returns(applications.AsQueryable().Expression);
mockApplicationSet.ElementType.Returns(applications.AsQueryable().ElementType);
mockApplicationSet.GetEnumerator().Returns(applications.AsQueryable().GetEnumerator());

mockApplicationSet.When(q => q.Add(Arg.Any<Application>()))
    .Do(q => applications.Add(q.Arg<Application>()));

mockApplicationSet.When(q => q.Remove(Arg.Any<Application>()))
    .Do(q => applications.Remove(q.Arg<Application>()));


mockDb.Applications.Returns(mockApplicationSet); //This is the line creating the error

完整的错误是:

测试方法 MyProjectName.Controllers.MyControllerTest.TestOfSectionImTesting 抛出异常: NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException: 找不到返回的呼叫。

确保在调用替代者后调用 Returns()(对于 例如:mySub.SomeMethod().Returns(value)),而你不是 在 Returns() 中配置其他替代品(例如,避免 这个:mySub.SomeMethod().Returns(ConfigOtherSub()))。

如果您替换为类而不是接口,请检查 对您的替代者的呼叫是在虚拟/抽象成员上。返回 不能为非虚拟/非抽象成员配置值。

正确使用:

mySub.SomeMethod().Returns(returnValue);

可能有问题的使用:

mySub.SomeMethod().Returns(ConfigOtherSub());

改为尝试:

var returnValue = ConfigOtherSub(); 

mySub.SomeMethod().Returns(returnValue);

但这在我的环境中不起作用,因为应用程序不是一种方法。就像我说的,这在我的另一个网站上工作得很好,所以它必须是我所缺少的一些基本的东西。我在网上找到的任何东西都对我的特殊情况没有帮助。我更新到最新版本的 NSubstitute 并卸载/重新安装,但仍然一无所获。

再次感谢您!

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-4 unit-testing nsubstitute


    【解决方案1】:

    NSubstitute 不能模拟非虚拟成员。 (有quite a few caveats to substituting for classes。)

    MyCoolApplicationsEntities.Applications 需要是虚拟的,.Returns() 才能工作。

    【讨论】:

    • 大卫,感谢您查看此内容。今天早上在同事的帮助下,我能够让它工作。如果你愿意,请看我的回答。再次感谢!
    • @Timothy,很高兴你把它整理好了!所以问题没有通过 IQueryable 接口?这意味着context.Applications.Returns(mockApplications) 现在应该可以正常工作了吗?
    • context.Applications.Returns(mockApplications) 仍然会出现相同的错误。 context.Applications = mockApplications 现在可以工作了。
    【解决方案2】:

    这是最终的工作:

    var context = Substitute.For<MyCoolApplicationsEntities>();
    
    var applications = new List<Application>
    {
        new Application {AppID = 1, ApplicationName = "MyCoolApplication"}
    };
    
    var mockApplications = Substitute.For<DbSet<Application>, IQueryable<Application>>();
    ((IQueryable<Application>)mockApplications).Provider.Returns(applications.AsQueryable().Provider);
    ((IQueryable<Application>)mockApplications).Expression.Returns(applications.AsQueryable().Expression);
    ((IQueryable<Application>)mockApplications).ElementType.Returns(applications.AsQueryable().ElementType);
    ((IQueryable<Application>)mockApplications).GetEnumerator().Returns(applications.AsQueryable().GetEnumerator());
    
    mockApplications.When(q => q.Add(Arg.Any<Application>()))
        .Do(q => applications.Add(q.Arg<Application>()));
    
    mockApplications.When(q => q.Remove(Arg.Any<Application>()))
        .Do(q => applications.Remove(q.Arg<Application>()));
    
    context.Applications = mockApplications;
    

    【讨论】:

      【解决方案3】:

      我看不到你的类,但你需要用虚拟成员创建接口,并让你的代码通过接口调用类,然后你就可以模拟出类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-08
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多