2013-04-24 146 views
7

我試圖通過添加一些硒功能擴展新的xUnit斷言類斷言

namespace MyProject.Web.Specs.PageLibrary.Extensions 
{ 
    public static class AssertExtensions 
    { 
     public static void ElementPresent(this Assert assert, ...) 
     { 
      if (...) 
      { 
       throw new AssertException(...); 
      } 
     } 
    } 
} 

延長的xUnit斷言方法但當我嘗試使用它,我得到這個編譯錯誤。

using MyProject.Web.Specs.PageLibrary.Extensions;  
using Xunit; 
... 

public void DoSomething() 
{ 
    Assert.ElementPresent(...); 
} 

和錯誤

Error 5 'Xunit.Assert' does not contain a definition for 'ElementPresent' 

有誰知道這是可能的,或者我要去哪裏錯了嗎?

回答

3

您需要將作爲此參數傳遞給擴展方法的對象實例。 在你的情況,這將是正確的語法

var assert = new Assert(); 
assert.ElementPresent(...); 

但我想你並不需要,甚至不能斷言創建類的實例。

你想要做的是調用擴展方法作爲擴展類的靜態調用,並且不會工作。 但是,爲什麼不只需撥打

AssertExtensions.ElementPresent(...); 
+0

謝謝,這解釋了爲什麼我無法斷言,延長像我想要的。你的解決方案几乎是我最終做的,但我打電話給我'SeleniumAssert.ElementPresent(...);' – Neil 2013-04-25 09:42:06

+1

對於xUnit 2,請查看https://github.com/xunit/samples.xunit /blob/master/AssertExtensions/StringAssertionExtensions.cs – Jedidja 2016-03-05 16:02:51

3

很抱歉,但你感到困惑(編輯:!所以是我)。 xUnit.net的Assert static,因此不能添加擴展名(儘管其他斷言庫不會提出這種方法,這就是爲什麼人們可能期望使用擴展方法來擴展 Assert)。因此,在xUnit.net Universe中,如果要添加自定義斷言,請添加具有不同名稱的新靜態類。

public static class AssertExtensions 
{ 
    public static void ElementPresent(this Assert assert, ...) 

到:

public class AssertExtensions : XUnit.Assert 
{ 
    public static void ElementPresent(...) 

,然後使用@加入BradWilson的慣用伎倆:

using Assert = MyProject.Web.Specs.PageLibrary.Extensions.AssertExtensions; 

您可以通過它來改變你的類讓你的方法工作任何需要擴展名的文件的頂部。

這種技術非常適合添加過載來想起來....

(最明顯的弱點是,你不能有一個以上的通過Assert.雖然直接訪問)

+0

Assert類不是靜態的,但裏面的方法是靜態的,這就是拋棄我的東西。查看@jure的解決方案 – Neil 2013-04-25 09:47:00

+0

@Neil。感謝downvote。我正在和@xunit進行交談,看看'Assert'是否可以成爲一個靜態類,以避免任何其他人遇到這種情況(這讓我感到驚訝,因爲xUnit.net依賴於允許靜態類的.NET 2.0,而我不能想想如何改變可能會破壞) – 2013-04-25 11:24:00

+0

@尼爾啊,似乎它可能已經開放,以啓用[這裏]描述的擴展技巧(https://xunit.codeplex.com/discussions/15792)。最後,我確信這是靜態的原因 - Brad Wilson自己告訴我這是: - https://xunit.codeplex.com/discussions/238521 – 2013-04-25 11:29:04

10

編輯2 xUnit 2最終最終將斷言移動到單獨的程序集中。 NuGet上只有編譯和源代碼包,而Assert類是部分的,所以通過使用包的源代碼版本,Assert變得非常容易擴展(在C#中)。

編輯爲了更加完整:xUnit 2刪除了這個擴展點,並建議使用沿着'流利'斷言庫的擴展方法。


爲了完整起見,這裏的延伸Assert的「官方」的描述(這些令人驚訝尚未在所有提到,儘管布拉德·威爾遜甚至加入了討論)。

從版本1.5(根據Brad的博客),xUnit.Extensions通過AssertionsTestClass類明確支持此類。它的工作原理是這樣的:

TestClass有一個名爲Assert屬性,是Assertions類型的繼電器上Xunit.Assert所有方法。因爲TestClass.Assert是一個實例,你可以在Assertions通過擴展方法方法添加到它:

public static class AssertionsExtensions 
{ 
    public static void DeepEquals(this Assertions assertions, XNode expected, XNode actual) 
    { 
     assertions.True(XNode.DeepEquals(expected, actual)); // You can also use Assert.True here, there's effectively no difference. 
    } 
} 

現在你需要讓你的測試類從Xunit.Extensions.TestClass(容易混淆的派生,也有Xunit.TestClass,這是不是你想要的),如果您不明確限定名稱,則Assert屬性將「隱藏」Xunit.Assert類型。

在您的測試類,從TestClass派生,你現在可以使用

Assert.DeepEquals(expectedXml, actualXml); 

唯一真正的區別,從內置的xUnit斷言(除了一個事實,即語法着色爲Assert是一個標識符,而不是類型)是,當它失敗時,您只需獲得一個TrueException,而不是一個具體的DeepEqualsException,它可以假設告訴你哪裏的比較失敗。但是,當然你也可以用同樣的方式來構建它。

+0

看看Ruben Bartelink的帖子..下面。結合這裏的知識,它會導致從全局創建你自己的派生類:: XUnit.Assert – Robetto 2015-07-09 13:19:30

+1

而對於xUnit 2,最簡單的方法是查看例如https://github.com/xunit/samples.xunit /blob/master/AssertExtensions/StringAssertionExtensions.cs – Jedidja 2016-03-05 16:02:41

3

解決方案摘要xUnit 2。 (在NuGet中爲我工作2.1.0版本。)

Assert是一個部分類,您可以通過添加另一部分來擴展。爲了能夠做到這一點,你需要從源代碼編譯Assert程序集。你可以使用xunit.assert.source NuGet來獲取源代碼。

步驟

  1. 刪除參照從項目xunit.assert NuGet包。
  2. 改爲安裝xunit.assert.source包。
  3. Xunit命名空間中,定義public partial class Assert並在其中添加自定義斷言。自定義斷言的

例子:

namespace Xunit 
{ 
    public partial class Assert 
    { 
     public static void ArraySegmentEqual<T>(
      T[] expectedSequence, T[] buffer, int offset = 0) 
     { 
      for (int i = 0; i < expectedSequence.Length; i++) 
      { 
       int b = i + offset; 

       True(buffer[b].Equals(expectedSequence[i]), 
        $"Byte #{b} differs: {buffer[b]} != {expectedSequence[i]}"); 
      } 
     } 
    } 
} 

注:其他答案,編輯還指出,解決方案,但它花了我不少大部頭從那裏弄明白。另外,我不認爲這是唯一或最好的選擇。

0

對於的xUnit 2+

1)添加xunit.assert.source NuGet包與擴展項目。

2)創建局部類定義:

namespace xUnit 
{ 
    public partial class Assert 
    { 
    public static void ElementPresent(...) 
    { 
    } 
    } 
}