2014-10-03 67 views
1

的價值我使用JustMock框架,並具有以下聲明:JustMock - 檢查傳遞方法參數

Mock.Assert(() => activityListenerMock.PeriodPassed(
    Arg.Matches<Period>(e => e.Length == expectedLength))); 

它失敗,晦澀的消息:

Occurrence expectation failed. Expected at least 1 call. Calls so far: 0 

我怎樣才能得到更好的消息。我想知道它被稱爲什麼價值。

方法實際上是調用,但有錯誤的說法,因爲當我改變斷言以下它通過:

Mock.Assert(() => activityListenerMock.PeriodPassed(
    Arg.IsAny<Period>())); 
+0

你能舉一個簡短但完整的例子嗎?這會讓你更容易幫助你。 – 2014-10-03 08:26:53

回答

5

的一種方式,看看傳遞給PeriodPassed什麼說法是使用JustMock的DebugView

廣場DebugView.IsTraceEnabled = true;在測試開始時,將DebugView.CurrentState加入手錶。接近尾聲時,您會看到如下內容: Invocations: (ByRef ...).PeriodPassed("period value will go here") called 1 time; (signature: ...)

週期值將顯示在調用列表中。

另一種方式來做到這一點,是將匹配提取到一個單獨的Lambda和使用斷點: Predicate<Period> matcher = e => e.Length == expectedLength; Mock.Assert(() => activityListenerMock.PeriodPassed( Arg.Matches<Period>(e => matcher(e))));

現在你可以將謂詞中的斷點,並檢查e參數的值。這是有效的,因爲現在謂詞不是一個表達式而是一個實際的函數,所以現在你可以調試它。

+0

設置DebugView.IsTraceEnabled = true將導致失敗消息包含DebugView.CurrentState的值。小心,但它會大大減慢你的測試。 – kevinpo 2016-01-18 17:37:36

0

添加額外的安排之前也爲我工作,但它是非常哈克:

Mock.Arrange(() => activityListenerMock.PeriodPassed(Arg.IsAny<Period>())). 
    DoInstead((Period p) => Console.WriteLine("Actual " + p.Length+" expected "+expectedLength)); 
3

只是爲了什麼斯特凡Dragnev寫道。我用他的想法,然後添加邏輯來驗證輸入。如果不是期望的值Assert.Fail()。不知道是否有更好的方法,但這個工程:

Mock.Arrange(() => _uowMock.Class.Add(
    Arg.Matches<ModelClass>(x => (CheckArgs(x, updated))))) 
    .DoNothing().Occurs(3); 

....

protected static bool CheckArgs(ModelClass x, int y) 
{ 
    if (x.val != y) 
    { 
     Assert.Fail("Houston we have a problem"); 
    } 

    return true; 
} 
0

就遇到了這個同樣的困境,今天開始對基耶斯洛夫的想法擴大一些帶有擴展名。這很粗糙,但功能。

public static class JustMockExtensions { 
     public static FuncExpectation<T> PrintParams<T, T1>(this FuncExpectation<T> mock) { 
      return mock.DoInstead<T1, T>((arg1, arg2) => { 
       string message = string.Empty; 
       message += Process(arg1); 
       message += Process(arg2); 
       Console.WriteLine(message); 
      }); 
     } 

     private static string Process<T>(T obj) { 
      if (typeof(T).IsEnum) { 
       return Enum.GetName(typeof(T), obj); 
      } 
      return obj.ToString(); 
     } 
    } 

到目前爲止,以這種方式使用它可以在正常流程中進行管道連接。

Mock.Arrange(() => foo.bar(Arg.IsAny<Widget>(), Arg.IsAny<WidgetTypeEnum>())) 
       .PrintParams<Widget, WidgetTypeEnum>() 
       .MustBeCalled();