我正在寻找一个Java工具,可以在我的测试中创建匿名变量(我不关心它的值的变量),类似于.Net中的AutoFixture.这是AutoFixture自述文件的链接,它有很好的例子.
以下是同一自述文件中的简短示例:
[TestMethod]
public void IntroductoryTest()
{
// Fixture setup
Fixture fixture = new Fixture();
int expectedNumber = fixture.CreateAnonymous<int>();
MyClass sut = fixture.CreateAnonymous<MyClass>();
// Exercise system
int result = sut.Echo(expectedNumber);
// Verify outcome
Assert.AreEqual<int>(expectedNumber, result, "Echo");
// Teardown
}
Run Code Online (Sandbox Code Playgroud)
Java世界中有这样的工具吗?
编辑:
我尝试过QuickCheck,虽然它设法做了我想要的事情:
import net.java.quickcheck.Generator;
import net.java.quickcheck.generator.PrimitiveGenerators;
import net.java.quickcheck.generator.support.ObjectGeneratorImpl;
public class Main {
interface Test{
String getTestValue();
}
public static void main(String[] args) {
Generator<String> stringGen = PrimitiveGenerators.strings(5, 100);
Generator<Integer> intGen = PrimitiveGenerators.integers(5, 20);
ObjectGeneratorImpl<Test> g = …
Run Code Online (Sandbox Code Playgroud) 我有以下课程:
class Foo
{
public Foo(string str, int i, bool b, DateTime d, string str2)
{
.....
}
}
Run Code Online (Sandbox Code Playgroud)
我正在Foo
使用AutoFixture 创建一个:
var foo = fixture.Create<Foo>();
Run Code Online (Sandbox Code Playgroud)
但我希望AutoFixture为str2
参数提供已知值,并为每个其他参数使用默认行为.
我尝试实现一个SpecimenBuilder
但我无法找到一种方法来获取与请求相关联的元数据,以便知道我是从Foo构造函数调用的.
有没有办法实现这个目标?
在使用Autofixture构建父级时,是否可以为子实例上的属性分配固定值?它会将默认值添加到子实例上的所有属性(如charm),但我想覆盖并为子实例上的某个属性指定特定值.
鉴于这种父/子关系:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public int Number { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想在地址实例上为City属性分配一个特定值.我正在考虑这个测试代码:
var fixture = new Fixture();
var expectedCity = "foo";
var person = fixture
.Build<Person>()
.With(x => x.Address.City, expectedCity) …
Run Code Online (Sandbox Code Playgroud) 我只需要使用System.Type从AutoFixture创建一个对象.但是,似乎没有过载CreateAnonymous()
,只需要一种类型.他们都期望编译时通用T.有没有办法将System.Type转换为T?
编辑使用细节:
我正在使用AutoMapper,它有一个用于注入组件的钩子,以支持复杂的映射场景:
void ConstructServicesUsing(System.Func<Type,object> constructor)
Run Code Online (Sandbox Code Playgroud)
从签名中可以看出,客户端可以注册Func
AutoMapper何时需要注入服务(主要是ValueResolver实现).
在生成版本中,此方法调用我的StructureMap容器来检索组件.但是,在单元测试我的映射代码时,我必须提供存根实现,否则AutoMapper会抛出异常.由于我使用AutoFixture + Moq作为我的自动锁定容器,因此让AF新建一个完全水合的存根似乎很自然,所以我可以集中精力编写单元测试代码.
我有一个创建字符串数组string []的问题,每次创建3个值但我希望能够控制它.
我在用
var tst = fixture.Create<string[]>();
Run Code Online (Sandbox Code Playgroud)
我也研究过使用CreateMany
但似乎返回了一种IEnumerable.
有人有主意吗 ?
我大量使用Autofixture AutoData Theories来创建我的数据和模拟.然而,这使我无法使用XUnit中的InlineData属性来管理我的测试的大量不同数据.
所以我基本上是在寻找这样的东西:
[Theory, AutoMoqDataAttribute]
[InlineData(3,4)]
[InlineData(33,44)]
[InlineData(13,14)]
public void SomeUnitTest([Frozen]Mock<ISomeInterface> theInterface, MySut sut, int DataFrom, int OtherData)
{
// actual test omitted
}
Run Code Online (Sandbox Code Playgroud)
这样的事情可能吗?
我有一个定制的自动混合构建器用于集成测试.代码如下.
问题1 -目前第一个事务有一个1 TransactionViewKey.TransactionId等如何设置TransactionViewKey TRANSACTIONID所以它是从方法PARAM播种beginningTransactionId?例如,返回第一个TransactionId为200的TransactionViews数组,然后每个递增1?
问题2 - 用于确定transactiondate的lambda似乎只运行一次 - 因此每个日期都是相同的值.如何设置构建器,以便为每个生成的实例运行随机日期生成器而不是仅运行一次?
谢谢
static TransactionView[] CreateTransactions(int transactionsToReturnCount, long beginningTransactionId) {
Random random = new Random();
IFixture fixture = new Fixture();
fixture.Customize<TransactionViewKey>(ob => ob
.With(t => t.TransactionId)
.With(t => t.TransactionIdSpecified, true)
.OmitAutoProperties()
);
fixture.Customize<TransactionView>(ob => ob
.With(t => t.TransactionDate, DateTime.Now - new TimeSpan(random.Next(30),0,0,0))
.With(t => t.PostDate, DateTime.Now - new TimeSpan(random.Next(30), 0, 0, 0))
.With(t => t.ViewKey)
.With(t => t.Amount)
.OmitAutoProperties()
);
IEnumerable<TransactionView> transactionViews = fixture.CreateMany<TransactionView>(transactionsToReturnCount);
return transactionViews.OrderBy(t => t.TransactionDate).ToArray();
}
Run Code Online (Sandbox Code Playgroud) 假设我有界面:
public interface IFoo
{
int Bar1 { get; set; }
int Bar2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如果IFoo
是上课,我可以写:
fixture.CreateAnonymous<IFoo>();
Run Code Online (Sandbox Code Playgroud)
结果将为Bar1
和设置数字Bar2
.
但是如何用界面做到这一点?我试图使用,AutoMoqCustomization
但这似乎是具有接口类型的属性,而不是接口本身.
我正在寻找像CreateAnonymous
课程一样的自动化方式.Currenlty我正在创建界面模拟并明确设置它的属性,这是我想要保存的工作.我必须遗漏一些明显的东西
我找到了一个有效的解决方案(使用DTO和AutoMapper),这个解决方案在下面转载,但我更喜欢一个答案,列出了问题的不同解决方法,如果收到,这将被标记为答案.
在我的实体模型中,我有一个从子实体到父实体的导航属性.我的项目正在游泳.然后我开始使用AutoFixture进行单元测试,测试失败,AutoFixture说我有一个循环引用.
现在,我意识到像这样的循环引用导航属性在Entity Framework中是可以的,但是我发现了这篇文章(在AutoFixture中创建复杂子元素时使用父属性的值),其中AutoFixture的创建者Mark Seemann说:
"为了记录,我多年来没有用循环引用编写API,因此很可能避免这些父/子关系."
所以,我想了解如何重构域模型以避免子/父关系.
下面是有问题的实体类,存储库方法,以及我如何在视图中使用导致循环引用的属性. 完美的答案将解释我可以从示例中选择的不同选项,以及每种方法的基本优缺点.
注意:在UserTeam模型中,导致循环引用的属性是User.
楷模:
public class UserProfile
{
public UserProfile()
{
UserTeams = new HashSet<UserTeam>();
Games = new HashSet<Game>();
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<UserTeam> UserTeams { get; set; }
public virtual ICollection<Game> Games { get; set; }
}
public class Game
{
public Game()
{
UserTeams = new HashSet<UserTeam>();
}
public int …
Run Code Online (Sandbox Code Playgroud) 目前我正在使用EF6在UnitOfWork中实现我的存储库.我还创建了一个In-Memory模拟实现(MockUnitOfWork和MockRepository),以便我可以在单元测试中使用它们,但是我现在必须处理对象的繁琐设置.
这不是Autofixture的设计目的吗?我如何获得可以在包含Foo和Barr存储库的测试中使用的MockUnitOfWork ?我正在使用NSubstitute作为我的模拟框架.
IUnitOfWork
public interface IUnitOfWork
{
void Save();
void Commit();
void Rollback();
IRepository<Foo> FooRepository { get; }
IRepository<Bar> BarRepository { get; }
}
Run Code Online (Sandbox Code Playgroud)
IRepository
public interface IRepository<TEntity> where TEntity : class
{
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null);
TEntity GetByID(object id);
void Insert(TEntity entity);
void Delete(object id);
void Delete(TEntity entityToDelete);
void Update(TEntity entityToUpdate);
}
Run Code Online (Sandbox Code Playgroud) autofixture ×10
c# ×8
unit-testing ×2
.net ×1
automapper ×1
hierarchy ×1
java ×1
mocking ×1
nsubstitute ×1
quickcheck ×1
reflection ×1
xunit ×1