我经常使用NSubstitute.我喜欢它.
我只是在研究AutoFixture.看起来很棒!
我见过NSFstitute的AutoFixture,并在Moq中看到了一些如何使用此功能的例子.
但我似乎无法将其翻译成NSubstitute.
我试过这个:
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
var addDest = Substitute.For<IPerson>();
Run Code Online (Sandbox Code Playgroud)
使用:
public interface IPersonEntity
{
int ID { get; set; }
string FirstName { get; set;}
string LastName { get; set;}
DateTime DateOfBirth { get; set; }
char Gender { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我得到一个对象,但没有填充任何属性(类似于AutoFixture的点).
我也尝试过:
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
var result = fixture.Create<IPersonEntity>();
Run Code Online (Sandbox Code Playgroud)
这也给了我一个没有填充属性的对象.(请注意,如果我使用PersonEntity类进行上述操作,则会填充属性.)
我确信有一种方法可以使这项工作,但我似乎无法找到它.
那么,鉴于我的IPersonEntity界面,有没有人知道如何使用AutoFixture和NSubstitute给我一个填充的IPersonEntity对象?
我试图使用autofixture来创建一个对象,但它们是我想要始终默认的某些属性(其余的可以自动生成).但是,每当我设置自定义时,它都会在我使用自定义构建时被覆盖.
void Main()
{
var fixture = new Fixture();
fixture.Customize<Person>(composer => composer.With(p => p.Name, "Ben"));
var person = fixture.Build<Person>()
.With(p => p.DateOfBirth, new DateTime(1900, 1, 1))
.Create();
/* RESULT OF person below
Name null
DateOfBirth 1/1/1900
StreetAddress StreetAddressafd6b86b-376a-4355-9a9c-fbae34731453
State State019e867b-ac5e-418f-805b-a64146bc06bc
*/
}
public class Person
{
public string Name { get; set;}
public DateTime DateOfBirth { get; set;}
public string StreetAddress { get; set;}
public string State { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
"Name"和"DateOfBirth"属性自定义不会发生冲突,因此我不知道为什么Name最终为null.我希望名字是"本".
如何获得它以便应用两种自定义(即Name ="Ben"和DateOfBirth = 1/1/1900?
我刚刚开始使用AutoFixture并拥有这个半复杂的数据结构,我想创建一些标本.在我正在使用的测试中,我不太关心数据结构的内容.我只想要合理的默认值.
此数据结构的一部分是递归树.更具体地说,一个类包含一些其他类的集合,其中包含自身的子列表.类似于:
public class A
{
private IEnumerable<B> bNodes;
public A(IEnumerable<B> bNodes)
{
this.bNodes = bNodes;
}
}
public class B
{
private IEnumerable<B> children;
public B(IEnumerable<B> children)
{
this.children = children;
}
}
Run Code Online (Sandbox Code Playgroud)
让我们假设我出于各种原因无法轻易改变这种结构.
如果我要求我的灯具创建一个ThrowingRecursionBehavior将开始咆哮B是递归的.
如果我用OmitOnRecursionBehavior替换ThrowingRecursionBehavior,我会得到一个ObjectCreateException.
如果我尝试类似:fixture.Inject(Enumerable.Empty()); 我从DictionaryFiller中得到"已添加相同键的项目".如果我用NullRecursionBehavior替换ThrowingRecursionBehavior,也会发生同样的事情.
我想要几件事.
对于我的遗愿,指定一些递归深度可能会很好,在此之后使用Enumerable.Empty(或零大小的数组/ List或甚至为null).我知道AutoFixture可以非常灵活地扩展.因此,我认为应该可以创建一些完全符合这一要求的样本构建器.事实上,我会尝试使用自定义的ISpecimenBuilder,但也许有人已经有了一个更智能的解决方案.例如,在RecursionGuard中修改此行是否有意义:
public object Create(object request, ISpecimenContext context)
{
if (this.monitoredRequests.Any(x => this.comparer.Equals(x, request)))
...
Run Code Online (Sandbox Code Playgroud)
至
public object Create(object request, ISpecimenContext context)
{
if (this.monitoredRequests.Count(x => this.comparer.Equals(x, request)) > maxAllowedRecursions)
...
Run Code Online (Sandbox Code Playgroud) 我目前正在拥有一个包含多个属性的模型类.简化模型可能如下所示:
public class SomeClass
{
public DateTime ValidFrom { get; set; }
public DateTime ExpirationDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,我正在使用NUnit实现一些单元测试,并使用AutoFixture创建一些随机数据:
[Test]
public void SomeTest()
{
var fixture = new Fixture();
var someRandom = fixture.Create<SomeClass>();
}
Run Code Online (Sandbox Code Playgroud)
这到目前为止完美无缺.但是要求日期ValidFrom 总是在之前 ExpirationDate.我必须确保这一点,因为我正在实施一些积极的测试.
那么使用AutoFixture 有一种简单的方法来实现它吗?我知道我可以创建一个修复日期并添加一个随机日期间隔来解决这个问题,但如果AutoFixture可以自己处理这个要求,那将会很棒.
我没有很多使用AutoFixture的经验,但我知道我可以ICustomizationComposer通过调用Build方法得到一个:
var fixture = new Fixture();
var someRandom = fixture.Build<SomeClass>()
.With(some => /*some magic like some.ValidFrom < some.ExpirationDate here...*/ )
.Create();
Run Code Online (Sandbox Code Playgroud)
也许这是实现这一目标的正确方法?
在此先感谢您的帮助.
我有很多使用MOQ的经验,而我最近偶然发现了AutoFixture.这些框架之间有什么区别?
我使用Nuget安装了Autofixture和Moq.So我有moq版本4.
运行以下代码时
var fixture = new Fixture().Customize(new AutoMoqCustomization());
fixture.CreateAnonymous<ISomething>();
Run Code Online (Sandbox Code Playgroud)
出现以下错误
System.IO.FileLoadException:无法加载文件或程序集'Moq,Version = 3.1.416.3,Culture = neutral,PublicKeyToken = 69f491c39445e920'
我也尝试将它重定向到v4,但没有运气.
<configuration>
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name="Moq" publicKeyToken="69f491c39445e920" culture="neutral"/>
<bindingRedirect oldVersion="3.1.416.3" newVersion="4.0.10827.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
这可能是什么问题?
我开始使用moq但是根据我的理解,我总是要模拟所有可以调用的方法,即使我真的不关心它们.
有时需要很长时间来模拟你忘记你想做什么的东西.所以我一直在看自动模拟,但我不确定我应该使用什么.
我根本不知道如何使用第一个.我有点得到第二个但从未真正尝试过.
我不确定一个人是否比另一个好.我唯一知道的是我使用AutoFixtures已经是第一个的依赖.
所以也许从长远来看,与第一个一起使用是有意义的,但就像我说我找不到任何关于如何使用它的基本教程.
编辑
我试图按照"Nikos Baxevanis"的例子,但我遇到了错误.
Failure: System.ArgumentException : A matching constructor for the given arguments was not found on the mocked type.
----> System.MissingMethodException : Constructor on type 'DatabaseProxyded46c36c8524889972231ef23659a72' not found.
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var fooMock = fixture.Freeze<Mock<IFoo>>();
// fooMock.Setup(x => x.GetAccounts(It.IsAny<IUnitOfWork>()));
var sut = fixture.CreateAnonymous<AdminService>();
sut.Apply();
fooMock.VerifyAll();
Run Code Online (Sandbox Code Playgroud)
我认为这是因为我的petapoco unitOfWork财产
PetaPoco.Database Db { get; }
Run Code Online (Sandbox Code Playgroud)
不确定我是否要以某种方式嘲笑这个或什么.
在这种情况下,我正在为特定类型创建一个AutoFixture样本构建器System.Data.DataSet.构建器将返回a FakeDataSet,这是DataSet为测试而定制的.
以下不起作用,dataSet总是返回null,即使DataSet正在请求a(我可以通过钻取request属性来判断).
public class DataSetBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var dataSet = request as DataSet;
if (dataSet == null)
{
return new NoSpecimen(request);
}
return new FakeDataSet();
}
}
Run Code Online (Sandbox Code Playgroud)
这种变化确实有效,但似乎过于复杂.感觉有更好的方法来完成同样的事情,我只是缺少一些东西.
public class DataSetBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var seededRequest = request as SeededRequest;
if (seededRequest == null)
{
return new NoSpecimen(request);
}
var requestType = seededRequest.Request …Run Code Online (Sandbox Code Playgroud) 假设我有这个具体的类:
public partial class User
{
public int ID { get; set; }
public string Email { get; set; }
public string FullName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个具有有效电子邮件地址的匿名实例,并且fullname字段不超过20个字符.我可以做这个:
var fixture = new Fixture();
var anonUser = fixture.Build<User>()
.With(x => x.Email, string.Format("{0}@fobar.com", fixture.Create<string>()))
.With(x => x.FullName, fixture.Create<string>()Substring(0,20))
.Create();
Run Code Online (Sandbox Code Playgroud)
有没有办法可以在一个地方定义它,所以AF知道我可以通过使用以下方式获得我的自定义anon类:
var newAnon = fixture.Build<User>();
Run Code Online (Sandbox Code Playgroud) 我有一个深度嵌套的对象模型,其中一些类可能看起来像这样:
class TBase { ... }
class TDerived : TBase { ... }
class Container
{
ICollection<TBase> instances;
...
}
class TopLevel
{
Container container1;
Container container2;
...
}
Run Code Online (Sandbox Code Playgroud)
我想将我的顶级对象创建为测试夹具,但我希望所有TBase实例(例如instances上面的集合中)都是实例TDerived而不是TBase.
我以为我可以简单地使用以下内容来做到这一点:
var fixture = new Fixture();
fixture.Customize<TBase>(c => c.Create<TDerived>());
var model = this.fixture.Create<TopLevel>();
Run Code Online (Sandbox Code Playgroud)
...但是这不起作用,因为lambda表达式Customize是错误的.我猜测有一种方法可以做到这一点,但AutoFixture似乎缺乏文档,而不是开发人员博客上的意识流.
谁能指出我正确的方向?