我想编写一个测试来检查给定命名空间中的类。必须检查返回任何类型列表的类的所有方法,如果它们返回 null。如果是这样,测试必须失败。
类/方法本身也有应该自动模拟的依赖项(构造函数参数和方法参数)。
AutoFixture 是否有一种机制来检查返回任何类型列表的方法从不返回 null?
示例类:
public class UserService
{
private readonly IRemotingFacade _remotingFacade;
public UserService(IRemotingFacade remotingFacade)
{
_remotingFacade = remotingFacade;
}
// directly return a list
public IEnumerable<User> GetUsers()
{
}
// directly return a list, pass method parameters
public IEnumerable<User> GetUsers(string filter)
{
}
// wrapped list
public IBusinessResponse<IEnumerable<User>> GetUsers()
{
}
// wrapped list, pass method parameters
public IBusinessResponse<IEnumerable<User>> GetUsers(string filter)
{
}
}
所以请考虑列表可以包含在另一个对象中。
最佳答案
AutoFixture 3.18.0 引入了一个名为 Idioms.FsCheck 的新胶水库,它使用 FsCheck 来实现可重用的
名为 ReturnValueMustNotBeNullAssertion
的断言。
这个新断言验证(或至少使可能)返回值 (Query) 的方法不返回 null。
安装
NuGet 上提供了 Idioms.FsCheck:
PM> Install-Package AutoFixture.Idioms.FsCheck
场景
UserService
使用 IRemotingFacade
的注入(inject)实例并公开两个 [1] 查询:场景 #1 :注入(inject)的
IRemotingFacade
实例返回 null:[Theory, UnitTestConventions]
public void Scenario1(
ISpecimenBuilder builder,
[Frozen]Mock<IRemotingFacade> stub)
{
stub.Setup(x => x.GetUsers()).Returns((User[])null);
var sut = from x in new Methods<UserService>() select x.GetUsers();
var assertion = new ReturnValueMustNotBeNullAssertion(builder);
Assert.Throws<ReturnValueMustNotBeNullException>(() =>
assertion.Verify(sut));
}
场景 #2 :注入(inject)的
IRemotingFacade
实例不返回 null:[Theory, UnitTestConventions]
public void Scenario2(
ISpecimenBuilder builder,
[Frozen]Mock<IRemotingFacade> stub,
User[] users)
{
stub.Setup(x => x.GetUsers()).Returns(users);
var sut = from x in new Methods<UserService>() select x.GetUsers();
var assertion = new ReturnValueMustNotBeNullAssertion(builder);
Assert.DoesNotThrow(() => assertion.Verify(sut));
}
场景 3 :如果
i
是 -1 GetUsers(int)
返回 null:[Theory, UnitTestConventions]
public void Scenario3(
ISpecimenBuilder builder,
[Frozen]Mock<IRemotingFacade> stub,
User[] users)
{
stub.Setup(x => x.GetUsers()).Returns(users);
var sut = from x in new Methods<UserService>()
select x.GetUsers(default(int));
var assertion = new ReturnValueMustNotBeNullAssertion(builder);
Assert.Throws<ReturnValueMustNotBeNullException>(
() => assertion.Verify(sut));
}
备注
If you only have F# 3.1 installed ,您还可以在 app.config 文件中添加程序集绑定(bind)重定向:
<dependentAssembly>
<assemblyIdentity name="FSharp.Core"
publicKeyToken="b03f5f7f11d50a3a"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.3.1.0"
newVersion="4.3.1.0" />
</dependentAssembly>
UnitTestConventionsAttribute
定义为:internal class UnitTestConventionsAttribute : AutoDataAttribute
{
internal UnitTestConventionsAttribute()
: base(new Fixture().Customize(new AutoMoqCustomization()))
{
}
}
反射查询使用 Albedo 执行。
[1] 为了演示,我简化了 original code 如下:
public class User
{
}
public interface IRemotingFacade
{
User[] GetUsers();
}
public class UserService
{
private readonly IRemotingFacade remotingFacade;
public UserService(IRemotingFacade remotingFacade)
{
if (remotingFacade == null)
throw new ArgumentNullException("remotingFacade");
this.remotingFacade = remotingFacade;
}
public User[] GetUsers()
{
return this.remotingFacade.GetUsers();
}
public User[] GetUsers(int i)
{
if (i == -1)
return null;
return this.remotingFacade.GetUsers();
}
}