我的代码中有几个类,这些类由XSD生成器工具根据XSD文件定义自动生成。这些类看起来很相似,但名称相似,但是基于XSD架构(我们已经从外部供应商那里收到),生成的类都是不同的类型。这些是非常复杂的类,具有许多深层嵌套的属性和枚举值。因此,我们过去常常直接使用类,因为很难采用通用的方法来使用类。
但是我接受了挑战,并且我成功了。为了避免在使用这些类时出现代码重复,我使用XSD生成的文件外部的接口定义为类添加了属性,以防止再次生成类时利用诸如以下的部分类声明来覆盖它们:
XSD生成的类的简化示例
public interface IXsdGeneratedClass
{
IXsdGeneratedClassHeader header { get; set; }
IXsdGeneratedClassBody body { get; set; }
}
接口的简化示例,其中的属性还包括类型接口,我们已编写了这些类型的接口以匹配XSD生成的类中的属性
public partial class xsdGeneratedClass1 : IXsdGeneratedClass
{
public IXsdGeneratedClassHeader header { get; set; }
public IXsdGeneratedClassBody body { get; set; }
}
public partial class xsdGeneratedClass2 : IXsdGeneratedClass
{
public IXsdGeneratedClassHeader header { get; set; }
public IXsdGeneratedClassBody body { get; set; }
}
我们在XSD生成的文件之外实现接口的简化示例
class1.Should().BeEquivalentTo(expectedClass);
在这个简化的示例中,此构造使我可以使用接口而不是具体的实现来处理标头和正文属性,因为我们拥有数十个结构相同但类型不同的类,而无需进行编辑XSD工具的自动生成的代码。这一切都很好,很花哨。
使用Fluent断言尝试比较单元测试中的对象时出现问题。似乎Fluent Assertions很难知道要比较的实例化对象的哪些属性。在这个简单的示例中,xsdGeneratedClass1的实例化对象将具有四个属性:
我要比较的对象是带有接口类型的header和body属性,因为这些将是其中唯一包含实际数据的对象。具体的类属性始终都是null。所以我做了这样的测试:
{{1}}
但是,似乎Fluent Assertions不断地将class1的IXsdGeneratedClassHeader标头与ExpectedClass的xsdGeneratedClass1Header标头进行比较,该标头为空。
我尝试使用RespectingRuntimeTypes选项,该选项使测试通过,但随后看来它没有像应有的那样比较对象。例如,如果我更改了ExpectedClass的header属性中的一个属性值,例如我知道它与class1中的值不匹配,则测试仍会通过。
我已经尝试搜寻互连网以寻找答案,并且在搜索过程中我已经走到了尽头,基本上我正在思考是应该编写自己的工具还是做出大量的手动断言。欧比旺断言,请帮忙!
答案 0 :(得分:0)
非常感谢Jonas Nyrup!似乎是一个缺陷,现在已在Fluent断言的主分支中进行了修订。同时,有人在github线程中发布了一个解决方法的答案,这也对我有用。很高兴。谢谢!
在某个地方声明此类,可在单元测试中使用
public class ReflectionMemberMatchingRule : IMemberMatchingRule
{
public SelectedMemberInfo Match(SelectedMemberInfo expectedMember, object subject, string memberPath, IEquivalencyAssertionOptions config) => expectedMember;
}
通过将配置添加到Fluent断言中,在单元测试中使用扩展类。
AssertionOptions.AssertEquivalencyUsing(x => x.Using(new ReflectionMemberMatchingRule()));
现在可以正常工作了!