以下是有关我们技术开发环境的信息:
• .NET 6
• C# 10
• Microsoft.NET.Test.Sdk”版本 15.5.0
• 起订量版本 4.18.2
• Xunit 版本 2.4.1
public class Vehicle { public string VIN { get; set; } public string CarCompany { get; set; } public string Model { get; set; } }
public interface IBlahClient : IDisposable { Task<TResponse> SendQuery<TResponse>( string aVehicleJsonString, CancellationToken cancellationToken = default); }
public class BlahClient : IBlahClient { public Task<TResponse> SendQuery<TResponse>( string aVehicleJsonString, CancellationToken cancellationToken = default) { Return ……; } }
public class VehicleProcessor { public static string ConvertToJSON( Vehicle aVehicle ){ …….blah blah blah blah code….. return aVehicleJsonString; }
public string SendVehicleInfoToDMV( IBlahClient client, Vehicle aVehicle ){ string aVehicleJsonString = ConvertToJSON(aVehicle ); string response = client. SendQuery<string>( aVehicleJsonString, CancellationToken.None); return response; }
}
public class VehicleProcessorSUTClass { [Fact] public void Test() { Vehicle aVehicle = ..…BlahBlah Code for instantiating a Vehicle instance….. string aVehicleJsonString = VehicleProcessor.ConvertToJSON( aVehicle ); VehicleProcessor aVehicleProcessorSUT = new VehicleProcessor(); Mock<IBlahClient> blahClientMock = new Mock<IBlahClient>(); blahClientMock.Setup(c => c.SendQuery<string>(aVehicleJsonString , CancellationToken.None)) .Returns(aVehicleJsonString); string response = aVehicleProcessorSUT. SendVehicleInfoToDMV(blahClientMock.Object, aVehicle ); //// Unfortunately response turns out to be null ///// } }
我理解两次调用 ConvertToJSON 的复杂微妙的细微差别,这将导致 2 个具有相同内容的不同 json 字符串实例:
在 Moq 测试代码中,我调用 ConvertToJSON ,并将结果用于 blahClientMock 的 SendQuery 方法的 Moq 设置。
在实际 SUT 的业务代码本身中,我调用 ConvertToJSON
但是,即使有 2 个不同的 aVehicleJsonString 实例,它们仍然具有相同的内容。为什么SUT业务代码在单元测试时返回null?
从您提供的代码中,有一些突出的事情可能导致问题:
方法名称不匹配:在
IBlahClient
接口中,您有一个名为 SendQueryAsync
的方法,但在 VehicleProcessor
类中,您正在调用名为 SendQuery
的方法。这将导致编译时错误。确保方法名称匹配。
异步/等待模式:
SendQueryAsync
方法是异步的,但在await
类中调用它时没有使用VehicleProcessor
关键字。这意味着您实际上并没有获得该方法的结果,而是获得了一个 Task
对象。您应该等待该方法才能获得结果。
模拟设置:当您设置模拟时,您使用的是方法
SendQuery<dynamic>
,但界面中的实际方法是SendQueryAsync<TResponse>
。这意味着您的模拟设置可能与实际的方法调用不匹配,因此模拟不会返回预期值,您会得到null
。
我已经提供了相关部分的更新版本:
VehicleProcessor
类以使用 await
:public async Task<string> SendVehicleInfoToDMV(IBlahClient client, Vehicle aVehicle)
{
string aVehicleJsonString = ConvertToJSON(aVehicle);
string response = await client.SendQueryAsync<string>(aVehicleJsonString, CancellationToken.None);
return response;
}
[Fact]
public async Task Test()
{
Vehicle aVehicle = ...; // Your code for instantiating a Vehicle instance
string aVehicleJsonString = VehicleProcessor.ConvertToJSON(aVehicle);
VehicleProcessor aVehicleProcessorSUT = new VehicleProcessor();
Mock<IBlahClient> blahClientMock = new Mock<IBlahClient>();
blahClientMock.Setup(c => c.SendQueryAsync<string>(aVehicleJsonString, CancellationToken.None))
.ReturnsAsync(aVehicleJsonString);
string response = await aVehicleProcessorSUT.SendVehicleInfoToDMV(blahClientMock.Object, aVehicle);
Assert.Equal(aVehicleJsonString, response); // Add this assertion to check if the response matches the expected value
}
BlahClient
类正确实现 SendQueryAsync
接口中的 IBlahClient
方法。我为您的测试提供的这些更改应该按预期工作。如果您仍然遇到问题,请确保
ConvertToJSON
方法是确定性的,并为相同的输入生成相同的 JSON 字符串。