2016-01-24 56 views
0
public MyContext _db; 
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
{ 
    if (_db == null || !_db.ChangeTracker.HasChanges()) 
    { 
     return; 
    } 

    try 
    { 
     _db.SaveChanges(); 
    } 
    catch 
    { 
    } 
} 

這是我爲我的WEP API項目行爲過濾器。按每個請求注入到此過濾器的_db上下文對象。我的意思是在所有在服務層完成的處理之後調用SaveChanges()方法一次。我的問題是如何測試這個過濾器?我怎樣才能模仿任何控制器或服務層中可能發生的異常情況,以及何時拋出異常saveChanges()永遠不會調用?我如何設置應用程序內任何地方發生異常的情況?我如何編寫單元測試此actionfilter

回答

0

如果在執行請求出現未處理異常則Exception屬性上actionExecutedContext將包含異常。這是框架的一部分,而不是你需要測試的東西。在您的測試中,您可以簡單地手動設置Exception屬性並聲明屬性採取正確的操作。

[Fact] 
public void Saves_data_on_failure() 
{ 
    var mockDbContext = new Mock<IDbContext>(); 
    var myAttribute = new MyAttribute(mockDbContext.Object); 

    var executionContext = new HttpActionExecutedContext 
    { 
     Exception = new Exception("Request failed.") 
    }; 
    myAttribute.OnActionExecuted(executionContext); 

    mockDbContext.Verify(d => d.SaveChanges()); 
} 

您可能還想考慮是否要爲所有類型的異常保存數據。數據可能處於無效/未知狀態。

1

上週我一直在爲我的WebAPI 2操作過濾器做同樣的事情。

我有一個動作過濾器來驗證我的ModelState,如果有任何錯誤,它會拋出一個帶有200 HTTPcode的錯誤列表。

的操作是這樣的:

public class ModelValidationActionFilterAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(HttpActionContext actionContext) 
     { 
      var modelState = actionContext.ModelState; 

      if (!modelState.IsValid) 
      { 
       actionContext.Response = ... 
      } 
     } 
    } 

單位測試

var httpControllerContext = new HttpControllerContext 
      { 
       Request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/someUri") 
       { 
        Content = new ObjectContent(typeof(MyModel), 
         new MyModel(), new JsonMediaTypeFormatter()) 
       }, 
       RequestContext = new HttpRequestContext() 
      }; 

      httpControllerContext.Request = new HttpRequestMessage(); 
      httpControllerContext.Request.SetConfiguration(new HttpConfiguration()); 
      var httpActionContext = new HttpActionContext { ControllerContext = httpControllerContext }; 

      var filter = new ModelValidationActionFilterAttribute(); 

      httpActionContext.ModelState.AddModelError("*", "Invalid model state"); 

      // act 
      filter.OnActionExecuting(httpActionContext); 

      // assert 
      httpActionContext.Response.ShouldNotBe(null); 
      httpActionContext.Response.ShouldBeOfType(typeof (HttpResponseMessage)); 
      var result = httpActionContext.Response.Content.ReadAsStringAsync().Result; 
      BaseServiceResponse<object> resultResponse = 
       JsonConvert.DeserializeObject<BaseServiceResponse<object>>(result); 

      resultResponse.Data.ShouldBe(null); 
      resultResponse.Messages.Count.ShouldBe(1); 
      resultResponse.Messages.First().Description.ShouldBe("Invalid model state"); 

在你的情況,你需要使用IDbContext接口嘲笑DB背景 - 在這裏看到:http://aikmeng.com/post/62817541825/how-to-mock-dbcontext-and-dbset-with-moq-for-unit

+0

我會upvote當我可以感謝 – kermanoz

相關問題