简体   繁体   English

MVC4单元测试NSubstitute无法找到从中返回的调用

[英]MVC4 Unit test NSubstitute Could not find a call to return from

I have a MVC4 web application I'm unit testing right now. 我有一个MVC4 Web应用程序,我现在正在进行单元测试。 It uses entity framework for the database portion. 它使用实体框架作为数据库部分。 I'm using NSubstitute to mock the database. 我正在使用NSubstitute来模拟数据库。 This code is basically copied and pasted from another site which works fine, so I hope I'm just missing something super simple. 这段代码基本上是从另一个工作中复制和粘贴的,工作正常,所以我希望我只是错过了一些非常简单的东西。

Thanks in advance! 提前致谢!

Applications table in SQL: SQL中的应用程序表:

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

Entity created the Application class: 实体创建了Application类:

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

The mock section of the unit test looks like this: 单元测试的模拟部分如下所示:

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

The full error is: 完整的错误是:

Test method MyProjectName.Controllers.MyControllerTest.TestOfSectionImTesting threw exception: NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException: Could not find a call to return from. 测试方法MyProjectName.Controllers.MyControllerTest.TestOfSectionImTesting引发异常:NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException:找不到要返回的调用。

Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)), and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())). 确保在调用替换后调用了Returns()(例如:mySub.SomeMethod()。返回(值)),并且您没有在Returns()中配置其他替换(例如,避免这样:mySub.SomeMethod( ).Returns(ConfigOtherSub()))。

If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member. 如果替换了类而不是接口,请检查对替换的调用是否在虚拟/抽象成员上。 Return values cannot be configured for non-virtual/non-abstract members. 无法为非虚拟/非抽象成员配置返回值。

Correct use: 正确使用:

 mySub.SomeMethod().Returns(returnValue); 

Potentially problematic use: 可能有问题的用途:

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

Instead try: 而是尝试:

 var returnValue = ConfigOtherSub(); mySub.SomeMethod().Returns(returnValue); 

But that doesn't work in my environment because Applications isn't a method. 但这在我的环境中不起作用,因为Applications不是一种方法。 Like I said, this works fine in another site of mine, so it's got to be something basic I'm missing. 就像我说的,这在我的另一个网站上工作得很好,所以它必须是我缺少的基本东西。 Nothing I've found online has been helpful with my particular case. 我在网上找到的任何内容都对我的具体情况有所帮助。 I updated to the newest version of NSubstitute and I uninstalled/reinstalled, but still have got nothing. 我更新到NSubstitute的最新版本,我卸载/重新安装,但仍然没有任何东西。

Again, thanks in advance! 再次,在此先感谢!

NSubstitute can not mock non-virtual members. NSubstitute不能模拟非虚拟成员。 (There are quite a few caveats to substituting for classes .) 替代课程很多注意事项 。)

MyCoolApplicationsEntities.Applications will need to be virtual for .Returns() to work. MyCoolApplicationsEntities.Applications将需要虚拟的.Returns()工作。

Here's what ended up working: 这是最终的工作:

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;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM