2013-04-24 5 views
7

Я пытаюсь распространить метод XUnit утверждает, добавив некоторые функции селенаРасширения XUnit Assert класса с новым утверждает

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

Но я получаю эту ошибку компиляции, когда я пытаюсь использовать его.

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

Вам нужен объект intance, который будет передан как этот аргумент методу расширения. В вашем случае это будет правильный синтаксис

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

Но я полагаю, что вам не нужно или даже не может создать экземпляр класса Assert.

Что вы пытаетесь сделать, это метод расширения вызова как статический вызов в расширенном классе, и это не сработает. Но почему бы просто не позвонить

AssertExtensions.ElementPresent(...); 
+0

Спасибо, что объясняет, почему я не мог получить утверждают продлить, как я хотел. Ваше решение в значительной степени связано с тем, что я закончил, но я назвал свой «SeleniumAssert.ElementPresent (...)»; – Neil

+1

Для xUnit 2 ознакомьтесь с примерами, например https://github.com/xunit/samples.xunit /blob/master/AssertExtensions/StringAssertionExtensions.cs – Jedidja

3

Извините, но вы путаетесь (EDIT: и так был я). xUnit.net's Assert - static и, следовательно, не может быть добавлены расширения (хотя другие библиотеки Assertion не подают в суд на этот подход, поэтому можно было бы использовать методы расширения для расширения Assert). Поэтому в юниверсе xUnit.net, если вы хотите добавить настраиваемое утверждение, добавьте новый статический класс с другим именем.

Вы можете сделать свой подход работу, изменив класс от:

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

+0

@Neil. Спасибо за нижний план. Я беседую с @xunit re, если «Assert» может стать статическим классом, чтобы избежать того, что кто-то еще работает в этом (для меня это неожиданность, поскольку это не так, как xUnit.net зависит от .NET 2.0, который позволяет статическим классам, а я не могу подумайте, как изменение может быть нарушено.) –

+0

@Neil Ah, кажется, он остался открытым, чтобы включить трюк расширения, описанный здесь (https://xunit.codeplex.com/discussions/15792). Наконец, причина, по которой я был так уверен, был «статичным» - сам Брэд Уилсон сказал мне, что это было: - https://xunit.codeplex.com/discussions/238521 –

10

Редактировать 2 xUnit 2 в конечном итоге полностью переместил утверждения в отдельную сборку. На NuGet есть и скомпилированные, и только исходные пакеты, а класс Assert является частичным, поэтому с использованием исходной версии пакета Assert становится очень легко расширяемым (в C#, то есть).

Редактировать Для получения дополнительной полноты: xUnit 2 удаляет эту точку расширения и рекомендует использовать методы расширения по строкам «свободно» библиотек утверждений.


Для полноты, вот описание «официальных» способ расширения Assert (что удивительно не упоминается вовсе, несмотря на то, что Брэд Уилсон даже присоединился к дискуссии).

Из версии 1.5 (согласно блогу Брэда) xUnit.Extensions имеет явную поддержку для этого через классыи TestClass. Вот как это работает:

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

Взгляните на сообщение Рубена Бартелькина ниже. Вместе со знанием здесь это приводит к созданию собственного производного от global :: XUnit.Assert – Robetto

+1

И для xUnit 2 проще всего проверить такие примеры, как https://github.com/xunit/samples.xunit /blob/master/AssertExtensions/StringAssertionExtensions.cs – Jedidja

3

Резюме решения для xUnit 2. (Работал для меня для версии 2.1.0 от NuGet.)

Assert - это частичный класс, который вы можете расширить, добавив еще одну часть. Чтобы это сделать, вам нужно собрать сборку Assert из источников. Вы можете использовать xunit.assert.source NuGet для получения источников.

Шаги

  1. Удалить ссылку на xunit.assert NuGet пакет из проекта.
  2. Вместо этого установите xunit.assert.source package.
  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(...) 
    { 
    } 
    } 
}