AutoFixture 自动填充对象数据,AutoMoq自动模拟对象
对于.net framwork项目,又是用到cookie的时候自动集成测试是比较麻烦的事情
引用xunit 2.0,AutoFixture,AutoMoq直接在方法上加上AutoDomainData声明就可以了,方便测试,不用自己new 对象。
测试类继承BaseTest的时候要初始化
HttpContext.Current = new HttpContext(new HttpRequest("", "http://localhost", ""), new HttpResponse(new StringWriter()));
然后写入cookie
后面的测试代码才能拿到cookie
如下:
[Theory]
[AutoDomainData]
public void ChangeDailyTest([Frozen] Mock<CRM_DailyInfoController> CRM_DailyInfoController, t_CRM_DailyInfo t_CRM_DailyInfo)
{
t_CRM_DailyInfo.DailyID = "00f57845d5e6b199d4097a521b9abec5";
dynamic result = CRM_DailyInfoController.Object.ChangeDaily(t_CRM_DailyInfo);
Assert.Equal(Json.Decode(result.Content).code, (int)EnumResultType.success);
}
public class BaseTest
{
public BaseTest() {
SetCookieToken = "2";
}
/// <summary>
/// 创建 Fixture实体,可以选构造参数
/// </summary>
/// <param name="t"></param>
/// <param name="typeArg"></param>
/// <returns></returns>
public static Func<IFixture> CreateFix(Type t=null, params Type[] typeArg)
{
return () =>
{
var fix = new Fixture();
fix.Customize(new AutoMoqCustomization());
if (t != null)
{//选择构造函数
fix.Customize(new ConstructorCustomization(t.GetType(), new MyMethodSelector(typeArg)));
}
fix.Customizations.Add(new CurrentDateTimeGenerator());
fix.Customizations.Add(new StringSpecimenBuilder());
return fix;
};
}
/// <summary>
/// 初始化为userid=2,admin账号
/// </summary>
public static string SetCookieToken {
set {
HttpContext.Current = new HttpContext(new HttpRequest("", "http://localhost", ""), new HttpResponse(new StringWriter()));
new UserBLL().SetTokenCatch(value, value);
WebHelper.WriteCookie("token", value);
}
}
public string CreateMail {
get {
var fix = new Fixture();
fix.Customizations.Add(new MailAddressGenerator());
var mr = fix.Create<MailAddress>();
return mr.Address;
}
}
public string CreateUrl
{
get
{
var fix = new Fixture();
fix.Customizations.Add(new UriGenerator());
var br = fix.Create<Uri>();
return br.LocalPath; ;
}
}
/// <summary>
/// 字符生成规则
/// </summary>
public class StringSpecimenBuilder : ISpecimenBuilder
{
private readonly int _strLenCount;
private readonly Random _random = new Random();
private DateTime startDate = DateTime.Now;
public StringSpecimenBuilder(int strLenCount = 6)
{
_strLenCount = strLenCount;
}
public object Create(object request, ISpecimenContext context)
{
//if (request is ConstrainedStringRequest)
//{
// var cons = request as ConstrainedStringRequest;
// return GetString(_random.Next(cons.MinimumLength, cons.MaximumLength));
//}
var property = request as PropertyInfo;
if (property == null)
{
return new NoSpecimen();
}
if (property.PropertyType == typeof(string))
{
//if (property.Name.ToLower().EndsWith("id"))
//{
// return GetString(_strLenCount);
//}
if (property.Name.ToLower().EndsWith("name"))
{
return GetNameString();
}
if (property.Name.ToLower().Contains("start") &&
(property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?)))
{
var stDate = context.Create<DateTime>();
startDate = stDate;
return startDate;
}
if (property.Name.ToLower().Contains("end") &&
(property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?)))
{
var endDate = startDate.AddDays(_random.Next(1, 20));
return endDate;
}
return property.Name + "_" + GetString(_strLenCount);
}
if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?))
{
if (property.Name.ToLower().StartsWith("is"))
{
return _random.Next(0,1);
}
}
return new NoSpecimen();
}
/// <summary>
/// 普通字符
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
string GetString(int count)
{
List<int> ints = new List<int>();
for (int i = 0; i < count; i++)
{
int value = _random.Next(97, 122);
ints.Add(value);
}
var charArr = ints.Select(Convert.ToChar).ToArray();
var str = string.Concat(charArr);
return str;
}
/// <summary>
/// 获取中文名称
/// </summary>
/// <returns></returns>
string GetNameString()
{
List<string> listName = new List<string>() {
"江山故宅空文藻,云雨荒台岂梦思。",
"白闻天下谈士相聚而言曰:生不用封万户侯,但愿一识韩荆州。",
"赏赐不能喜,诛罚不能威",
"衣懒换,酒难赊。可怜此夕看梅花。",
"低花树映小妆楼,春入眉心两点愁。",
"瘦应因此瘦,羞亦为郎羞。",
"把酒祝东风。且共从容。",
"日晚江南望江北,寒鸦飞尽水悠悠。",
"离恨远萦杨柳,梦魂长绕梨花。",
"水际轻烟,沙边微雨。荷花芳草垂杨渡。",
"闻君有他心,拉杂摧烧之。",
"夕殿萤飞思悄然,孤灯挑尽未成眠。",
"竹怜新雨后,山爱夕阳时。",
"万树梅花一潭水,四时烟雨半山云。",
"巧媳妇煮不得没米粥",
"浮生如此,别多会少,不如莫遇。",
"虱多不痒,债多不愁。 ",
"快马不用鞭催,响鼓不用重锤。",
"學者不患才之不贍,而患志之不立。",
"秋水才深四五尺,野航恰受两三人。",
"大家渐及消亡,难期其复振,势成于因循也。",
"看花东陌上,惊动洛阳人。",
"玉雪窍玲珑,纷披绿映红。",
"扁鹊不能肉白骨,微、箕不能存亡国也。",
"君子耳不听淫声,目不视邪色,口不出恶言",
"不觉碧山暮,秋云暗几重。",
"善守者,藏于九地之下,善攻者,动于九天之上",
"此时此夜难为情!",
"精卫衔微木,将以填沧海。",
"野花不种年年有,烦恼无根日日生。",
"月落星稀天欲明,孤灯未灭梦难成。",
"君子进则能达,退则能静。岂贵其能达哉?贵其有功也。岂贵其能静哉?贵其能守也。",
"君自故乡来,应知故乡事。",
"离愁渐远渐无穷,迢迢不断如春水。",
"江南几日又天涯,谁与寄相思?",
"常读口里顺,常写手不笨。",
"相思休问定何如。情知春去后,管得落花无。",
"蜡炬风摇帘不下,竹影半墙如画。",
"芙蓉老秋霜,团扇羞网尘。",
"长记平山堂上,欹枕江南烟雨,杳杳没孤鸿。",
"君子不自大其事,不自尚其功",
"山月皎如烛,风霜时动竹。",
"众人重利,廉士重名,贤士尚志,圣人贵精。",
"君子遗人以财,不若善言。",
"满地黄花堆积。憔悴损,如今有谁堪摘?",
"芳草年年惹恨幽。想前事悠悠。",
"离骚痛饮,笑人生佳处,能消何物。",
"刑当罪则威,不当罪则侮",
"事有机缘,不先不后,刚刚凑巧。命若蹭蹬,走来走去,步步踏空。",
"曾因国难披金甲,不为家贫卖宝刀。",
};
int value = _random.Next(0, listName.Count);
return listName[value];
}
}
/// <summary>
/// 调用指定构造函数
/// var fix = new Fixture();
/// fix.Customize(new ConstructorCustomization(typeof(Person),
/// new MyMethodSelector(typeof(string), typeof(int))));
/// </summary>
public class MyMethodSelector : IMethodQuery
{
private readonly Type[] _types;
public MyMethodSelector(params Type[] type)
{
_types = type;
}
public IEnumerable<IMethod> SelectMethods(Type type)
{
if (type == null)
{
throw new ArgumentNullException();
}
var constructors = type.GetConstructors();
Func<ParameterInfo, bool> predicate = param => true;
if (_types != null && _types.Length == 1 && typeof(Nullable) == _types[0])
{
predicate = param => param.HasDefaultValue==true && param.DefaultValue==null;
var method2= constructors.Where(a => a.GetParameters().Where(predicate).Any()) .Select(a => new ConstructorMethod(a));
return method2;
}
var method= constructors.Where(a => a.GetParameters().Where(predicate).Select(t => t.ParameterType).SequenceEqual(_types))
.Select(a => new ConstructorMethod(a));
return method;
}
}
/// <summary>
/// 数据声明属性
/// </summary>
public class AutoDomainDataAttribute : AutoDataAttribute
{
public AutoDomainDataAttribute() : base(CreateFix())
{
}
/// <summary>
/// 模拟对象,对象参数
/// 如:
/// [Theory]
/// [AutoDomainData(typeof(CRM_ErpCompanyBLL),typeof(Nullable))]
/// </summary>
/// <param name="t"></param>
/// <param name="type"></param>
public AutoDomainDataAttribute(Type t = null, params Type[] type) : base(CreateFix(t, type))
{
}
}
}