Is there some kind of way to let AutoFixture create properties with an internal setter?
I've looked at the AutoFixture source and found that in the AutoPropertiesCommand the GetProperties method checks whether a property has GetSetMethod() != null. With an internal setter this returns null, unless you set the ignorePublic argument to true.
The easiest thing would ofcourse be to make the setter public but in the project i'm working on this just wouldn't be the right solution.
Below is a simplified piece of code from the project as an example.
public class Dummy
{
public int Id { get; set; }
public string Name { get; internal set; }
}
public class TestClass
{
[Fact]
public void Test()
{
var dummy = new Fixture().Create<Dummy>();
Assert.NotNull(dummy.Name);
}
}
Ideally, the tests shouldn't have to interact with the internal
members of a class, since they are explicitly excluded from its public API. Instead, these members would be tested indirectly by the code paths initiated through the public API.
However, if this isn't feasible in your particular situation, a possible workaround could be to explicitly assign a value to the internal properties from within the tests.
You can do that in one of two ways:
InternalsVisibleTo
attribute.In your example, option 1 would be:
// [assembly:InternalsVisibleTo("Tests")]
// is applied to the assembly that contains the 'Dummy' type
[Fact]
public void Test()
{
var fixture = new Fixture();
var dummy = fixture.Create<Dummy>();
dummy.Name = fixture.Create<string>();
// ...
}
Option 2, instead, would be something like:
public class Dummy : IModifiableDummy
{
public string Name { get; private set; }
public void IModifiableDummy.SetName(string value)
{
this.Name = value;
}
}
[Fact]
public void Test()
{
var fixture = new Fixture();
var dummy = fixture.Create<Dummy>();
((IModifiableDummy)dummy).SetName(fixture.Create<string>());
// ...
}
Option 1 is fairly quick to implement, but has the side effect of opening up all internal members within the assembly, which may not be what you want.
Option 2, on the other hand, allows you to control what part of the object's state should be exposed as modifiable, while still keeping it separated the object's own public API.
As a side note, I'd like to point out that, since you're using xUnit, you can take advantage of AutoFixture's support for Data Theories to make your tests slightly more terse:
[Theory, AutoData]
public void Test(Dummy dummy, string name)
{
((IModifiableDummy)dummy).SetName(name);
// ...
}
If you prefer to set the Name
property to a known value while still keeping the rest of the Dummy
object anonymous, you have also the possibility to combine the two within the same Data Theory:
[Theory, InlineAutoData("SomeName")]
public void Test(string name, Dummy dummy)
{
((IModifiableDummy)dummy).SetName(name);
// ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With