我是自动修复的新手,希望您能为您提供帮助。在使用XUnit的[Theory]属性和AutoDataAttribute 时,如何在对象中设置某些属性,而将其他属性保留为AutoFixture的默认设置-。
例如,在下面基于杰森·罗伯特(Jason Robert)的Pluralsight课程设计的“机场”示例中,设置属性(或“机场”对象)时,例如
f.Customize<Mock<IAirport>>(c => c.Do(m => m.SetupGet(i => i.code).Returns("NOO")));
其他属性通常为null,或者我必须手动设置它们而不是让AutoFixture来做。我更喜欢使用更简洁的代码,其中fixtureFactory设置Airport的所有属性,以便仅通过单个Airport参数传递V2单元测试。
因此,在fixtureFactory中
谢谢!
using AutoFixture;
using AutoFixture.AutoMoq;
using AutoFixture.Xunit2;
using Moq;
using System;
using Xunit;
namespace AirportTesterWithAutoFixture
{
public interface IAirport
{
string city { get; set; }
string code { get; set; }
string country { get; set; }
string name { get; set; }
void CallAirTrafficControl();
}
public class Airport : IAirport
{
public string name { get; set; }
public string city { get; set; }
public string code { get; set; }
public string country { get; set; }
public Airport()
{
}
public Airport(string name, string code, string country, string city)
{
this.name = name;
this.code = code;
this.country = country;
this.city = city;
}
public void CallAirTrafficControl()
{
if (this.country.Equals("Canada") && this.code.StartsWith("Y"))
{
// Send "Bonjour!"();
}
else
{
throw new Exception("Invalid code for Canada");
}
}
}
public class UnitTest1
{
[Fact]
public void V1_Validate_ExceptionThrown_ForInvalidCanadianAirportCode()
{
var fixture = new Fixture();
var sut = fixture.Create<Airport>();
// Overwrite code and country with invalid setting for Canada.
sut.country = "Canada";
sut.code = "NOT";
Assert.ThrowsAny<Exception>(() => sut.CallAirTrafficControl());
}
[Theory]
[AutoMoqInvalidAirportDataAttribute]
public void V2_Validate_ExceptionThrown_ForInvalidCanadianAirportCode(IAirport sut, string name, string city)
{
Airport airport = new Airport(name, sut.code, sut.country, city);
Assert.ThrowsAny<Exception>(() => airport.CallAirTrafficControl());
}
}
// https://stackoverflow.com/questions/58998834/how-to-use-ifixture-buildt-with-automoqcustomization-when-t-is-an-interface
public class AutoMoqInvalidAirportDataAttribute : AutoDataAttribute
{
public static Func<IFixture> fixtureFactory = () =>
{
IFixture f = new Fixture().Customize(new AutoMoqCustomization());
f.RepeatCount = 5;
// How do you set MULTIPLE properties?
// How does one use the default AutoFixture values rather than leaving the uninitialized values as null?
// Can one pass a custom property used earlier in the Fixture creation process to another custom property used later?
f.Customize<Mock<IAirport>>(c => c.Do(m => m.SetupGet(i => i.code).Returns("NOT")));
return f;
};
public AutoMoqInvalidAirportDataAttribute() : base(fixtureFactory)
{
}
}
}
答案 0 :(得分:1)
默认情况下,AutoFixture不会填充模拟属性,但是可以完成。这些博客文章描述了如何做到这一点:
https://blog.ploeh.dk/2013/04/05/how-to-configure-automoq-to-set-up-all-properties/
https://blog.ploeh.dk/2013/04/08/how-to-automatically-populate-properties-with-automoq/
但是,AutoFixture的作者不推荐这种方法,因为他认为接口中的属性声明是一种设计气味。 不幸的是,我找不到关于此主题的原始讨论,但在评论中它隐藏在StackOverflow的某个位置。翻阅Mark Seemann的个人资料,也许您就可以找到它。