2013-04-14 24 views
3

我想驗證我測試的方法已被調用一個特定的表達式。我花了幾個小時就沒有想要的結果。使用起訂量來驗證表達參數

這是被測系統

public class sut 
{ 
    private IEntityUtil _ew; 
    public sut(IEntityUtil ew) 
    { 
     _ew = ew; 
    } 

    public void Search() 
    { 
     Guid id = Guid.Parse("CB594050-3845-4EAF-ABC5-34840063E94F"); 
     var res = _ew.SelectSingle<Post>(w => w.Id == id, new PersonalSiteEntities()); 
    } 

} 

這是依賴

public interface IEntityUtil 
{ 
    TEntity SelectSingle<TEntity>(Expression<Func<TEntity, bool>> predicate, System.Data.Objects.ObjectContext ctx) 
     where TEntity : EntityObject; 
    List<TEntity> SelectList<TEntity>(Expression<Func<TEntity, bool>> predicate, System.Data.Objects.ObjectContext ctx) 
     where TEntity : EntityObject; 
    bool Insert<TEntity>(TEntity entity, System.Data.Objects.ObjectContext ctx) 
     where TEntity : EntityObject; 
} 

這就是我是多麼想測試

public class tst 
{ 
    [TestMethod] 
    public void tst1() 
    { 
     var cwMock = new Mock<ConsoleApplication1.IEntityUtil>(); 

     Guid id = Guid.Parse("CB594050-3845-4EAF-ABC5-34840063E94F"); 

     //cwMock.Setup(x => x.SelectSingle<ConsoleApplication1.Post>(w => w.Id == id, It.IsAny<System.Data.Objects.ObjectContext>())).Returns(new ConsoleApplication1.Post()).Verifiable(); 


     //cwMock.Setup(x => x.SelectSingle(It.IsAny<Expression<Func<ConsoleApplication1.Post, bool>>>(), It.IsAny<System.Data.Objects.ObjectContext>())).Returns(new ConsoleApplication1.Post()).Verifiable(); 


     Expression<Func<ConsoleApplication1.Post, bool>> func = (param) => param.Id == id; 

     cwMock.Setup(x => x.SelectSingle<ConsoleApplication1.Post>(func, It.IsAny<System.Data.Objects.ObjectContext>())).Returns(new ConsoleApplication1.Post()); 

     var sut = new ConsoleApplication1.sut(cwMock.Object); 

     sut.Search(); 

     //cwMock.VerifyAll(); 

     cwMock.Verify(x => x.SelectSingle(func, It.IsAny<System.Data.Objects.ObjectContext>())); 
    } 


} 

請注意第二評論設置將使測試通過,但它不會讓我確認一個特定的表達式已被傳入。

在此先感謝。

+0

那麼,什麼是你的結果?哪裏有問題? moq執行不正確嗎? – Mic

回答

1

兩件事情,這將極大地幫助(我們來幫助你)是

  1. 給你測試一個有意義的名字,所以我們知道你在做什麼之後,
  2. 安排測試分爲三個方面,獨立通過評論或空白:

    • 安排,
    • 法,
    • 斷言

這使得它更清楚一點的動作是什麼。

這就是說,在我看來你試圖斷言ew.SelectSingle被稱爲sut.Search()時被調用一次?

另外我注意到你在測試中創建了Guid,但從未做過任何事情。所以,這裏是你的測試快捷提案(不使用IDE,所以你可能會發現錯誤):

[Fact] 
    public void Verify_SelectSingle_IsCalledOnce(){ 

     Guid id = Guid.Parse("CB594050-3845-4EAF-ABC5-34840063E94F"); 
     var cwMock = new Mock<ConsoleApplication1.IEntityUtil>(); 
     var post = new ConsoleApplication1.Post{ Id = id }; 
     cwMock 
      .Setup(x=> x.SelectSingle<ConsoleApplication1.Post>(It.IsAny<Guid>)) 
      .Returns(post); 
     var sut = new ConsoleApplication1.sut(cwMock.Object); 



     sut.Search(); 



     cwMock.Verify( 
      x=> x.SelectSingle(It.IsAny<ObjectContect>(o => o.Id == id)), 
      Times.Once); 
    } 
0

如前所述,這是很難告訴你要完成什麼,因爲你的天堂」讓你的測試名稱明確。也就是說,它看起來像你需要提供一個回調到你的模擬設置,這將允許你驗證表達式。像這樣的東西應該幫助你(使用註釋掉的設置是通過):

cwMock.Setup(x => x.SelectSingle(It.IsAny<Expression<Func<ConsoleApplication1.Post, bool>>>(), It.IsAny<System.Data.Objects.ObjectContext>())).Callback<Expression<Func<ConsoleApplication1.Post, bool>>>(VerifyExpression).Returns(new ConsoleApplication1.Post()).Verifiable(); 

然後創建一個回調方法

private static void VerifyExpression(Expression<Func<ConsoleApplication1.Post, bool>> expression) 
{ 
    var func = expression.Compile(); 
    // call func(params) and verify against it 
}