- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Autofixture 进行单元测试,使用自动生成的数据。
为了测试一个简单的 Controller 端点(通过 Id 获取员工),我正在做类似的事情:
[Theory, AutoData]
public void GetEmployeeById_ValidId_ReturnsExpectedModel(
EmployeeModel expectedEmployee,
[Frozen] Mock<IEmployeeService> employeeServiceMock,
EmployeesController sut)
{
employeeServiceMock
.Setup(x => x.GetEmployeeById(42))
.Returns(expectedEmployee);
var actual = sut.GetEmployeeById(42);
actual.As<OkObjectResult>().Value.As<EmployeeModel>()
.Should().BeEquivalentTo(expectedEmployee);
}
和 Controller :
[HttpGet("{id:int}")]
public IActionResult GetEmployeeById(int id)
{
var employee = employeeService.GetEmployeeById(id);
if (employee == null)
return NotFound("Employee not found");
return Ok(employee);
}
在此单元测试中,expectedEmployee
是使用“随机”数据自动生成的。 sut(被测系统)被配置为生成所有必需的依赖项(其中之一是 IEmplyeeService
)。
这个单元测试的问题是,如果我在从 Controller 返回员工之前更改它,测试仍然会通过(因为它引用了同一个对象):
employee.SomeInternalModel.FooProperty = "Foo";
return Ok(employee);
所以,我认为上面的单元测试很糟糕。
为了使单元测试在这种情况下失败,我需要传递一个单独的对象:EmployeeModel
的深拷贝:
employeeServiceMock
.Setup(x => x.GetEmployeeById(42))
.Returns(expectedEmployee.DeepCopy());
我没有时间和资源为我的所有模型编写深拷贝方法。
如何轻松地自动生成相同的模型?我考虑过对 AutoFixture
进行播种,但它似乎不支持此功能。
你有什么优雅的建议吗?
最佳答案
我想你需要问这个问题你在测试什么?在您的测试用例中,您只测试SUT
是否返回 employee
由 service
返回; IMO它是否是同一个实例并不重要。更新属性不应破坏这个测试。
虽然你触及了一个更广泛的问题,但在其他情况下你真的想比较你的 expected
用actual
通过 structural equality
在这种情况下,您可以(例如使用 xUnit
s MemberData
)使用 builder
当你调用它两次时它会生成两个实例:
var employee = new EmployeeModelBuilder().Build();
可以使用 With()
增强此类构建器方法:
var employee = new EmployeeModelBuilder().With(name: "John").Build();
或者您可以使用 new EmployeeModel {}
内联创建这些对象.
结构相等意味着您需要一个覆盖 Equality
的对象成员(member)或使用 IEqualityComparer<>
在你的断言中。
更新
如果您不想使用自定义构建器(如您所说),您可以指示 AutoFixture
生成具有特定属性集的对象。如果您随后要求它创建一个实例两次(一次为您的 expected
一次为注入(inject)您的 SUT
的服务返回的实例),您可以比较 expected
与 actual
在你的Assert
阶段。
[Fact]
public void Sut_ReturnsEmployee_FromService()
{
var fixture = new Fixture();
fixture.Customize<EmployeeModel>(e => e.With(x => x.Name, "Foo"));
var expected = fixture.Create<EmployeeModel>();
var foundEmployee = fixture.Create<EmployeeModel>();
var employeeServiceMock = new Mock<IEmployeeService>();
employeeServiceMock.Setup(f => f.GetEmployeeById(42)).Returns(foundEmployee);
var sut = new EmployeeController(employeeServiceMock.Object);
var actual = sut.GetEmployeeById(42);
Assert.Equal(expected.Name, actual.Name);
}
这里我使用了 [Fact]
并且断言比较两个特定属性是否相等,但是当您比较结构相等时,您可以只比较对象本身(如上所述)。现在您可以验证您的 SUT
返回预期的实例而不篡改和而不使用对同一实例的两个引用。
关于c# - 使用 Autofixture 生成副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58543959/
我刚刚更改了我的 [RegularExpression] 验证,我三分之一的单元测试失败了! 事实证明 AutoFixture 正在根据该正则表达式生成值,这很酷,但它不理解所有正则表达式,所以我想为
我使用 Autofixture 作为 SUT 工厂,但在卡住空实例时遇到困难。 我想做这样的事情: _fixture.Freeze(c => null); 但很快就意识到这是错误的。我已经用这个解决了
我想以不确定的方式自动生成方法的返回值,即每次调用/测试运行时,我都希望方法返回随机值。目前它总是返回方法调用的默认值: public interface IReturn {
给定这些类: public class DrumAndBassBand { public Drums Drum { get; set; } public Bass Bass { get
我正在将我的测试移植到 AutoFixture 2.0 ,而且我遇到了一些我既无法解释也无法解决的奇怪行为。这个简单的测试对我来说失败了: var autoFixtures = new Fixture
我正在研究一个相当嵌套的模型,它有一些循环引用。它还使用 Entity Framework ,因此所有列表都是 ICollection .为了适应这一点,我正在像这样配置 AutoFixture: _
我正在尝试使用 NSubstitute (1.8.2)、AutoFixture (3.33) 和 AutoFixture.AutoNSubstitute (3.33),如下所示: 我有一个 poco,
当我添加一个新的 TracingBehavior到自动夹具 Fixture实例使用 fixture.Behaviors.Add(new TracingBehavior()); 我在我的 R# 单元测试
我目前正在使用 EF Core Code First Approach,并且我有以下域类: public class Employee { // several properties such a
我刚刚开始使用 AutoFixture,我正在了解基础知识(从我所看到的还有更多),但我遇到了一个问题,我不能 100% 确定对于此类事情的最佳实践是什么。 我正在测试一个 Controller ,该
我在我的单元和集成测试中使用 AutoFixture 并遇到了问题。我正在生成数据传输对象,其中一些类在属性上具有 DataAnnotation 属性(其中一些是自定义的)。 AutoFixture
如何设置确定性测试以验证列表中的项目是否已排序? 首先,我执行以下操作: public void SyncListContainsSortedItems( [Frozen] SyncItem[
默认情况下,AutoFixture在“本地未指定时间”中创建DateTime结构。 我一直在尝试找到一种方法来配置它以创建具有UTC类型的DateTime结构,但是到目前为止没有成功。 有没有办法做到
是否可以在卡住后解冻对象类型? 如果我有一个使用 DateTime 的对象 Appointment,有没有办法做这样的事情? var time = fixture.Freeze(); IEnumera
有什么办法可以给 AutoFixture 一个对象的实例,让它通过所有的 setter 并设置随机数据? wiki 示例仅显示如何从 AutoFixture 获取实例,例如 var autoGener
在我使用 AutoFixture 之前的日子里,我可能做了以下安排来设置名为 CustomerService 的服务的单元测试: public void TestName() { //Arrang
我正在尝试编写这个简单的测试: var fixture = new Fixture().Customize(new AutoMoqCustomization()); var postProcessin
我正在尝试使用 SUT Factory “模式”来创建我的 SUT。 给定 SUT 结构: namespace MySut { public class Dep1 { }
我正在使用的域模型有很多循环引用。事实上,可以从图中的任何点到达大多数对象。许多这些循环引用也在集合中。所以一个 Booking将收藏 Students其中有 Courses 的集合其中有 Booki
我遇到了这个错误。 Ploeh.AutoFixture.Kernel.IllegalRequestException : A request for an IntPtr was detected. T
我是一名优秀的程序员,十分优秀!