I'm trying to extend the xUnit assert method by adding some selenium functionality
namespace MyProject.Web.Specs.PageLibrary.Extensions
{
public static class AssertExtensions
{
public static void ElementPresent(this Assert assert, ...)
{
if (...)
{
throw new AssertException(...);
}
}
}
}
But I get this compile error when I try to use it.
using MyProject.Web.Specs.PageLibrary.Extensions;
using Xunit;
...
public void DoSomething()
{
Assert.ElementPresent(...);
}
And the error
Error 5 'Xunit.Assert' does not contain a definition for 'ElementPresent'
Does anyone know if this is possible or where I'm going wrong?
Edit 2 xUnit 2 eventually ended up moving the assertions into a separate assembly altogether. There are both compiled and source only packages of this on NuGet, and the Assert
class is partial, so by using the source only version of the package, Assert
becomes very easily extensible (in C#, that is).
Edit For more completeness: xUnit 2 removes this extension point and recommends using extension methods along the lines of 'fluent' assertion libraries.
For completeness, here's a description of the "official" way of extending Assert
(which surprisingly has not been mentioned at all, despite the fact that Brad Wilson even joined the discussion).
From version 1.5 (according to Brad's blog), xUnit.Extensions has explicit support for this via the Assertions
and TestClass
classes. It works like this:
TestClass
has a property called Assert
that is of type Assertions
which relays all the methods on Xunit.Assert
. Because TestClass.Assert
is an instance, you can add methods to it through extension methods on 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.
}
}
Now you need to have your test class derive from Xunit.Extensions.TestClass
(confusingly, there is also Xunit.TestClass
, which is not what you want), and the Assert
property will "shadow" the Xunit.Assert
type if you don't qualify the name explicitly.
In your test class that derives from TestClass
, you can now use
Assert.DeepEquals(expectedXml, actualXml);
The only real difference from a built-in xUnit assertion (apart from the fact that syntax coloring for Assert
is that of an identifier, not a type) is that when it fails, you simply get a TrueException
, not a specific DeepEqualsException
that could hypothetically tell you where the comparison failed. But of course you could build that too in the very same way.