121

I'm new to xUnit.net and AutoFixture.

I'm currently working on a "testproject" to get familiar with xUnit.net and Autofixture. There is one little thing I don't understand.

What is the difference between [Fact] and [Theory, AutoMoqData]?

Could you please tell me if the following two pieces of code are equal? I'm asking this because the Test succeeds with both, but I want to learn it the right way.

[Fact]
public void UpdateVersionWillUpdateCorrectlyInRepository()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var contract = fixture.Create<VersionContract>();
    var version = fixture.Create<Version>();

    fixture.Freeze<Mock<IContractMapper>>()
        .Setup(r => r.Map(contract)).Returns(version);

    var repMock = fixture.Freeze<Mock<VersionRepository>>();

    var sut = fixture.Create<VersionManagementService>();

    sut.UpdateVersion(contract);

    repMock.Verify(r => r.UpdateVersion(version));
}

and

[Theory, AutoMoqData]
public void UpdateVersionWillUpdateCorrectlyInRepository(
    VersionContract contract,
    Version version,
    [Frozen]Mock<IContractMapper> mapMock,
    [Frozen]Mock<VersionRepository> repMock,
    VersionManagementService sut)
{
    mapMock.Setup(r => r.Map(contract)).Returns(version);

    sut.UpdateVersion(contract);

    repMock.Verify(r => r.UpdateVersion(version));
}

What makes me think that there is a difference are the Keywords [Fact] and [Theory].

I'm assuming that the [Theory] Keywords tells the xUnit.net framework that the supplied data comes from somewhere, where somewhere is Autofixture. Whereas [Fact] tells xUnit nothing about the origin of the data and I need to build the objects manually.

svick
  • 236,525
  • 50
  • 385
  • 514
sternze
  • 1,524
  • 2
  • 9
  • 15

2 Answers2

133

Assuming that your [AutoMoqData] attribute looks something like this:

public class AutoMoqDataAttribute : AutoDataAttribute
{
    internal AutoMoqDataAttribute()
        : base(new Fixture().Customize(new AutoMoqCustomization()))
    {
    }
}

Then, yes, those two tests are equivalent.

Both [Fact] and [Theory] attributes are defined by xUnit.net.

The [Fact] attribute is used by the xUnit.net test runner to identify a 'normal' unit test: a test method that takes no method arguments.

The [Theory] attribute, on the other, expects one or more DataAttribute instances to supply the values for a Parameterized Test's method arguments.

xUnit.net itself supplies various attributes that derive from DataAttribute: [InlineData], [ClassData], [PropertyData].

AutoFixture hooks into this extensibility point of xUnit.net by supplying the [AutoData] attribute. It can be used to make tests more declarative.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • 2
    Thanks for the explanation! Yes, my AutoMoqData-Attribute looks like yours. BTW: I like your "Dependency Injection in .NET Book and my "Testproject" is build on it! – sternze Mar 13 '14 at 13:08
  • @BjörnAliGöransson No, `AutoDataAttribute` is defined in *AutoFixture.XUnit* and *AutoFixture.XUnit2*. – Mark Seemann Oct 10 '16 at 13:02
  • 5
    Is it just me that finds the terms not to be clear ? they are `Test`s, but to me a `Fact` and a `Theory` are very different. You might test a theory, but not a fact ... dunno ... language is har d... – Noctis Sep 14 '18 at 05:13
  • 3
    @Noctis To be honest, I, too, find the terms *fact* and *theory* somewhat contrived, but that's the naming choice made by the *xUnit.net* team... – Mark Seemann Sep 14 '18 at 05:36
8

Facts are tests which are always true. They test invariant conditions.

Theories are tests which are only true for a particular set of data.

source: https://xunit.net/docs/getting-started/netfx/visual-studio

inxss
  • 85
  • 2
  • 7