Asp.net mvc 创建操作的单元测试。同时运行所有测试会导致某些测试方法出错

Asp.net mvc 创建操作的单元测试。同时运行所有测试会导致某些测试方法出错,asp.net-mvc,unit-testing,Asp.net Mvc,Unit Testing,我的看法 这是我的测试方法,它为创建操作提供所有有效数据。当我单独运行此测试时,它成功通过。但是当我用其他测试方法运行这个测试时,它会给出错误 我的单元测试: public ActionResult Create(ViewModel vm) { if(ModelState.IsValid) { Model modelToCreate = new Model(); modelToCreate.Name = vm.Name; model

我的看法

这是我的测试方法,它为创建操作提供所有有效数据。当我单独运行此测试时,它成功通过。但是当我用其他测试方法运行这个测试时,它会给出错误

我的单元测试:

public ActionResult Create(ViewModel vm)
{
    if(ModelState.IsValid)
    {
        Model modelToCreate = new Model();
        modelToCreate.Name = vm.Name;
        modelToCreate.Address = vm.Address;
        lond Id = _createService.Create(modelToCreate);
        return RedirectToAction("Index");//If everything goes fine then user is redirected to "Index" View
    }
    return View(vm);//If model state is not valid user is sent to the create view
}
这就是错误:

public void createUnitTest()
{
    //Arrange
    var vm = new vm()
    {    
       Name = "xyz",
       Address = "mno street,Bikaner,Rajasthan"
       CategoryId = 1 //I am having a table "category" in my Dummy Database "TestDb" which contains this property
    }           

    //Act
    var result = controller.Create(vm) as RedirectToRouteResult;

    //Assert
    Assert.AreEqual("Index",result.RouteValues["action"]);
}
System.Data.Entity.Infrastructure.DbUpdateException:更新条目时出错。有关详细信息,请参见内部异常。-->System.Data.Entity.Core.UpdateException:更新条目时出错。有关详细信息,请参见内部异常。-->System.Data.SqlClient.SqlException:INSERT语句与外键约束“FK_dbo.FaqSet_dbo.FaqCategory_FaqCategoryId”冲突。冲突发生在数据库“TestFaq”、表“dbo.FaqCategory”、列“Id”中。
声明已终止。
结果跟踪:
位于System.Data.SqlClient.SqlConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction)
位于System.Data.SqlClient.SqlInternalConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction)
位于System.Data.SqlClient.TdsParser.ThroweException和Warning(TdsParserStateObject StateObjectStateObj、布尔调用方连接锁、布尔异步关闭)
位于System.Data.SqlClient.TdsParser.TryRun(RunBehavior RunBehavior、SqlCommand cmdHandler、SqlDataReader dataStream、BulkCopySimpleResultSet bulkCopyHandler、TdsParserStateObject stateObj、Boolean和dataReady)
位于System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()处
在System.Data.SqlClient.SqlDataReader.get_MetaData()处
位于System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds、RunBehavior、String ResetOptions String)
位于System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、Boolean async、Int32超时、任务和任务、Boolean asyncWrite、SqlDataReader ds)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法、TaskCompletionSource`1 completion、Int32超时、Task&Task、Boolean asyncWrite)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法)
位于System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior,String方法)
位于System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior)
位于System.Data.Common.DbCommand.ExecuteReader(CommandBehavior)
在System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.b_uÈc(DbCommand t,DbCommandInterceptionContext`1c)
在System.Data.Entity.Infrastructure.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget目标,Func`3操作,TInterceptionContext拦截Context,操作`3执行,操作`3执行)
位于System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand命令,DbCommandInterceptionContext interceptionContext)
位于System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior)
位于System.Data.Common.DbCommand.ExecuteReader(CommandBehavior)
在System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues,List`1 generatedValues)
位于System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()处
---内部异常堆栈跟踪的结束---
位于System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()处
位于System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.b__2(UpdateTranslator ut)
位于System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult,Func`2 updateFunction)
位于System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()处
位于System.Data.Entity.Core.Objects.ObjectContext.b__35()
在System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 Func,IDBEcutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)
位于System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions选项、IDBEcutionStrategy executionStrategy、Boolean startLocalTransaction)
在System.Data.Entity.Core.Objects.ObjectContext.c__DisplayClass2a.b__27()中
在System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1操作)中
位于System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions选项,布尔值executeInExistingTransaction)
位于System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions)
位于System.Data.Entity.Internal.InternalContext.SaveChanges()处
---内部异常堆栈跟踪的结束---
位于System.Data.Entity.Internal.InternalContext.SaveChanges()处
在System.Data.Entity.Internal.LazyInternalContext.SaveChanges()中
位于System.Data.Entity.DbContext.SaveChanges()处
在d:\project\FAQ.Repository\Common\UnitOfWork.cs中的FAQ.Repository.UnitOfWork.Commit()处:第49行
在d:\project\FAQ.Service\Common\EntityService.cs中的FAQ.Service.EntityService`1.Create(T实体):第35行
在d:\project\FAQ.Web\Controllers\FaqSetController.cs中的FAQ.Web.Controllers.FaqSetController.Create(FaqSetModel faqset)中
在FAQ.Web.Tests.Controllers.FaqSetControllerTest.FAQ\u Set\u为所有有效的\u输入创建\u Test\u,d:\project\FAQ.Web.Tests\Controllers\FaqSetControllerTest.cs中的\u No\u空白\u字段()

问题在于,为了单独测试代码的各个部分,您的依赖项没有被正确分离

lond Id=\u createService.Create(modelToCreate)在数据层中隐藏错误,即使您只是在测试控制器功能

我处理这个问题的方法是使用依赖注入和模拟框架

您可以实现依赖项注入b
public void createUnitTest()
{
    //Arrange
    var vm = new vm()
    {    
       Name = "xyz",
       Address = "mno street,Bikaner,Rajasthan"
       CategoryId = 1 //I am having a table "category" in my Dummy Database "TestDb" which contains this property
    }           

    //Act
    var result = controller.Create(vm) as RedirectToRouteResult;

    //Assert
    Assert.AreEqual("Index",result.RouteValues["action"]);
}
System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the  entries. See the inner exception for details. ---> System.Data.Entity.Core.UpdateException: An error  occurred while updating the entries. See the inner exception for details. --->          System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint  "FK_dbo.FaqSet_dbo.FaqCategory_FaqCategoryId". The conflict occurred in database "TestFaq", table  "dbo.FaqCategory", column 'Id'.
The statement has been terminated.
Result StackTrace:  
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection,  Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
    at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
 at System.Data.SqlClient.SqlDataReader.get_MetaData()
 at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
 at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
 at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
 at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
 at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
 at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
 at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
 at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
 at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
 at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
 at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
 at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
 at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues)
 at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
 --- End of inner exception stack trace ---
  at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
 at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut)
 at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction)
 at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update()
 at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35()
 at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
 at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
 at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27()
 at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
 at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
 at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
 at System.Data.Entity.Internal.InternalContext.SaveChanges()
 --- End of inner exception stack trace ---
  at System.Data.Entity.Internal.InternalContext.SaveChanges()
 at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
 at System.Data.Entity.DbContext.SaveChanges()
 at FAQ.Repository.UnitOfWork.Commit() in d:\project\FAQ.Repository\Common\UnitOfWork.cs:line 49
 at FAQ.Service.EntityService`1.Create(T entity) in d:\project\FAQ.Service\Common\EntityService.cs:line 35
 at FAQ.Web.Controllers.FaqSetController.Create(FaqSetModel faqset) in d:\project\FAQ.Web\Controllers\FaqSetController.cs:line 179
 at FAQ.Web.Tests.Controllers.FaqSetControllerTest.Faq_Set_Create_Test_For_All_Valid_Inputs_With_No_Blank_Field() in d:\project\FAQ.Web.Tests\Controllers\FaqSetControllerTest .cs:line 1260
ICreateService _createService { get; set; }
public class FriendlyCreateService : ICreateService
{
    public void Create(Model modelToCreate)
    {
        // do nothing
    }
}
public void createUnitTest()
{
    //Arrange
    var vm = new vm()
    {    
       Name = "xyz",
       Address = "mno street,Bikaner,Rajasthan",
       CategoryId = 1
    };          

    // Inject friendly service
    controller._createService = new FriendlyCreateService();

    //Act
    var result = controller.Create(vm) as RedirectToRouteResult;

    //Assert
    Assert.AreEqual("Index",result.RouteValues["action"]);
}
public void createUnitTest()
{
    // create a controller with a mocked ICreateService
    var mocks= new Mockrepository();
    Controller controller = new Controller
    {
        _createService = mocks.DynamicMock<ICreateService>();
    } 

    //Arrange
    var vm = new vm()
    {    
       Name = "xyz",
       Address = "mno street,Bikaner,Rajasthan",
       CategoryId = 1 
    }           

    //Act
    var result = controller.Create(vm) as RedirectToRouteResult;

    //Assert
    Assert.AreEqual("Index",result.RouteValues["action"]);
}