Unit testing FAKEITESY-如何验证嵌套参数值C#
我需要您的帮助,以便找到一种方法来验证作为测试调用下的方法的参数传递的嵌套对象的值。 假设这一类:Unit testing FAKEITESY-如何验证嵌套参数值C#,unit-testing,fakeiteasy,Unit Testing,Fakeiteasy,我需要您的帮助,以便找到一种方法来验证作为测试调用下的方法的参数传递的嵌套对象的值。 假设这一类: public class AuditTrailValueObject { public ActionType Action { get; private set; } public EntityType EntityType { get; private set; } public long EntityId { get; private set; } public
public class AuditTrailValueObject
{
public ActionType Action { get; private set; }
public EntityType EntityType { get; private set; }
public long EntityId { get; private set; }
public DateTime StartTime { get; private set; }
public bool IsSuccess { get; private set; }
public string Remarks { get; private set; }
public AuditTrailValueObject(ActionType action, EntityType entityType, long entityId, DateTime startTime, bool isSuccess, string remarks = "")
{
Action = action;
EntityType = entityType;
EntityId = entityId;
StartTime = startTime;
IsSuccess = isSuccess;
Remarks = remarks;
}
}
以下接口将该类作为注入依赖项:
public interface IAuditTrailService
{
void WriteToAuditTrail(AuditTrailValueObject auditParamData);
}
现在我有了ScanService
,这取决于AuditTrailService
(它实现了IAuditTrailService
):
我写的测试:
[TestMethod]
public void Scan_GivenProjectId_ShouldAuditSuccess()
{
//Given
var projectId = 100;
var scanService = CreateScanService();
...
A.CallTo(() => _scanRequestWriteModelFactory.Create(projectDetails)).Returns(new ScanRequestWriteModel());
A.CallTo(() => _scanRequestsWriteRepository.Insert(A<ScanRequestWriteModel>._)).Returns(1);
//When
var scanRequestId = scanService.CreateScanRequest(projectId);
//Then
A.CallTo(() => _auditTrailService.WriteToAuditTrail(
new AuditTrailValueObject(ActionType.Run, EntityType.SastScanRequest, scanRequestId, A<DateTime>._, true, A<string>._))).MustHaveHappened();
}
[TestMethod]
公共无效扫描\u给定项目\u应审核成功()
{
//给定
var-projectd=100;
var scanService=CreateScanService();
...
A.CallTo(()=>_scanRequestWriteModelFactory.Create(projectDetails)).Returns(new ScanRequestWriteModel());
A.CallTo(()=>_scanRequestsWriteRepository.Insert(A.)).Returns(1);
//什么时候
var scanRequestId=scanService.CreateScanRequest(projectId);
//然后
A.CallTo(()=>_auditTrailService.WriteToAuditTrail(
新的AuditTrailValueObject(ActionType.Run、EntityType.SastScanRequest、scanRequestId、A.。0、true、A.。0))。必须已发生();
}
运行此测试时,我得到:
System.InvalidCastException:指定的强制转换无效
如何验证
AuditTrailValueObject
中嵌套参数的值?您的问题是一个更大问题的症状:您试图在一个测试中做得太多
由于您正在WriteToAuditTrail()方法中新建AuditTrailValueObject的实例,因此无法访问此对象实例,因为它是在方法范围内创建的,因此不受检查
但是,您希望首先访问此对象的唯一原因似乎是为了验证其中设置的值是否正确
在这些值中,只有一个(在您的代码示例允许的范围内)是从调用方法中设置的。这是对_scanRequestsWriteRepository.Insert()调用的返回值,它应该是它自己的单元测试的主题,在这里,您可以独立于它的使用位置来验证正确的行为
编写这个单元测试(在_scanRequestsWriteRepository.Insert()方法上)实际上可以解决问题的根本原因(即您在单个测试中做的太多)。然而,你眼前的问题仍然需要解决。最简单的方法是完全删除AuditTrailValueObject类,然后直接将参数传递给WriteToAuditTrail()调用
如果我要删除AuditTrailValueObject,我应该在哪里验证
正在向auditTrailService传递哪些参数?我的意思是
如果我测试过auditTrailService,我也需要知道这一点
如果参数正确,则扫描服务调用(例如:使用
ActionType.Run,而不是与ActionType.Update一起运行)
要验证是否已将正确的参数传递给对WriteToAuditTrail()的调用,可以插入一个假的IAuditTrailService并验证调用是否已发生:
A.CallTo(
() => _auditTrailService.WriteToAuditTrail(
ActionType.Run,
EntityType.SastScanRequest,
scanRequestId,
myDateTime,
true,
myString)
).MustHaveHappened();
@tom redfern提出了许多好的观点,您可能希望解决这些问题。但是在重新阅读了你的代码和评论之后,我想我有了一个直接的方法。您的代码至少有一个问题,可能还有另一个问题 让我们看看
A.CallTo(() => _auditTrailService.WriteToAuditTrail(
new AuditTrailValueObject(ActionType.Run,
EntityType.SastScanRequest,
scanRequestId,
A<DateTime>._,
true
A<string>._)))
.MustHaveHappened();
有些人对
匹配中的复杂约束不感兴趣,因此另一种选择是捕获AuditTrailValueObject
并稍后进行查询,正如Alex James Brown在对的回答中所述。您能告诉我们错误发生在哪里吗?你有堆栈跟踪吗?有什么能缩小范围的吗?在这个问题上你已经抛出了很多代码。也许可以咨询一下,重新表述一下这个问题。我确实拿走了你所有的代码并试图复制。我遇到了一些问题,因为遗漏了很多东西,我不得不猜测。此外,您的测试也无法编译:我认为您有一个重复的“a.CallTo(()=>_auditTrailService.WriteToAuditTrail”(“行)。如果您纠正这些问题并提供完整的测试输出,我将重试。@BlairConrad我已修复了您注意到的错误行。是否希望我上载所有遗漏的行(可能会更累…)?我认为最好是指出无效强制转换的来源。如果捕获到异常,请包括异常,包括整个堆栈跟踪。(考虑到您已经包含的代码数量,更多的代码并不是更糟。我认为要么削减额外的代码位,直到您有一个非常集中的示例,要么包含足够的代码来编译和运行。)@BlairConrad我知道问题来自于a.CallTo(()=>\u auditTrailService.WriteToAuditTrail(**新**AuditTrailValueObject
(如@tomredffern所述)。我正在寻找另一种方法来验证传递给writeToAuditTrail
方法的值scanService
。@tomredffern从概念上讲,我同意你的观点。我不确定我是否完全理解你的意思。我要验证的值是AuditTrailValueObject
字段,如ActionType.Run
,EntityType.SastScanRequest
。这些值不是\u scanRequestsWriteRepository.Insert()返回对象的一部分
invocation。因此,我的问题是,如果我不使用您建议的更改,我如何验证这些值?@Roni-我知道您正在尝试验证哪些值。但是,我要说的是,这不是进行此类验证的地方。验证这些值的地方是在创建时,而不是在使用时。其他y、 我的意思是,您可以更进一步,完全删除AuditTrailValueObject对象。我在代码中看不到它存在的原因。您不需要它-它除了存储值之外什么都不做。如果我删除AuditTrailValueObject
我应该在哪里验证哪些参数被传递到auditTrail硒
A.CallTo(() => _auditTrailService.WriteToAuditTrail(
new AuditTrailValueObject(ActionType.Run,
EntityType.SastScanRequest,
scanRequestId,
A<DateTime>._,
true
A<string>._)))
.MustHaveHappened();
A.CallTo(() => _auditTrailService.WriteToAuditTrail(A<AuditTrailValueObject>.That.Matches(
a => a.Action == ActionType.Run &&
a.EntityType == EntityType.SastScanRequest &&
a.EntityId == scanRequestId &&
a.IsSuccess)))
.MustHaveHappened();