模拟 IList 的单元测试方法
Unit test method mocking IList
我正在尝试模拟以下方法 TryGetApns:
private readonly Func<string, ICommunicationClient> _communicationFactory;
public CommunicationApiFacade(Func<string, ICommunicationClient> communicationFactory)
{
_communicationFactory = communicationFactory;
}
public IList<ApnResponse> TryGetApns(string tenant)
{
GetApnsResponse response = null;
try
{
var communicationApiClient = _communicationFactory(tenant);
response = communicationApiClient.JctConfigurationService.GetApns();
}
catch (HttpException e)
{
...
}
return response?.Apns ?? new List<ApnResponse>();
}
通过以下测试:
private Mock<ICommunicationApiFacade> _communicationApiFacade;
[SetUp]
public void SetUp()
{
_fixture = new Fixture()
.Customize(new AutoMoqCustomization());
_communicationApiFacade = _fixture.Freeze<Mock<ICommunicationApiFacade>>();
}
[Test]
public void RunJctTests_WhenJctIsInAPrivateNetwork_ShouldReturnAPassedTest()
{
// Arrange
var jctApn = _fixture.Create<string>();
var message = _fixture.Build<JctLoggedIn>()
.With(x => x.ApnFromDevice, jctApn)
.Create();
var response = _fixture.Build<ApnResponse>()
.With(x => x.IsPrivateApn, true)
.With(x => x.ApnName, jctApn).Create();
_communicationApiFacade.Setup(x => x.TryGetApns(string.Empty))
.Returns(new List<ApnResponse> { response });
var subject = _fixture.Create<NetworkProviderTestRunner>();
// Act
var result = subject.Execute(message);
// Assert
Assert.That(result.Result, Is.True);
}
这是 NetworkProviderTestRunner class:
private readonly ICommunicationApiFacade _communicationApi;
public NetworkProviderTestRunner(ICommunicationApiFacade communicationApi)
{
_communicationApi = communicationApi;
}
public JctTest Execute(JctLoggedIn message)
{
var apns = _communicationApi.TryGetApns(message.Tenant);
var jctApn = apns.FirstOrDefault(x => x.ApnName == message.ApnFromDevice);
if (jctApn != null)
{
var privateApn = apns.FirstOrDefault(x => x.PublicApnId.Equals(jctApn.Id));
if (privateApn != null || jctApn.IsPrivateApn)
return new JctTest { Result = true };
}
return new JctTest { Result = false };
}
JctLoggedIn class:
public class JctLoggedIn : Message
{
public string Imei { get; set; }
public string SimCardIdFromDevice { get; set; }
public string SimCardIdFromStorage { get; set; }
public string ApnFromDevice { get; set; }
public string ApnFromStorage { get; set; }
public string FirmwareFromDevice { get; set; }
public int DeviceTypeFromStorage { get; set; }
public int SerialNumber { get; set; }
}
但出于某种原因,我总是得到一个空列表。我试图在 SetUp 中填充列表并在那里定义输出,但我总是一样。有帮助吗?
这一行
_communicationApiFacade.Setup(x => x.TryGetApns(string.Empty))
.Returns(new List<ApnResponse> { response });
告诉模拟 return 包含响应的列表,当调用 TryGetApns 时租户参数为空字符串。
此行创建消息后 message.Tenant 的值是多少:
var message = _fixture.Build<JctLoggedIn>()
.With(x => x.ApnFromDevice, jctApn)
.Create();
如果不是 string.empty,您的模拟将不会 return 响应列表。
替换
var response = _fixture.Build<ApnResponse>()
.With(x => x.IsPrivateApn, true)
.With(x => x.ApnName, jctApn).Create();
和
var response = _fixture.Build<ApnResponse>()
.With(x => x.Tenant, String.Empty)
.With(x => x.IsPrivateApn, true)
.With(x => x.ApnName, jctApn).Create();
如果租户是可写的。
如果 属性 是可写的,AutoFixture 将为租户创建一个具有非空值的对象,而无需明确设置您想要的内容。
虽然您可以在构建 message
对象时明确省略 Tenant
属性,但您也可以将 Mock 设置更改为:
_communicationApiFacade.Setup(x => x.TryGetApns(message.Tenant))
.Returns(new List<ApnResponse> { response });
我正在尝试模拟以下方法 TryGetApns:
private readonly Func<string, ICommunicationClient> _communicationFactory;
public CommunicationApiFacade(Func<string, ICommunicationClient> communicationFactory)
{
_communicationFactory = communicationFactory;
}
public IList<ApnResponse> TryGetApns(string tenant)
{
GetApnsResponse response = null;
try
{
var communicationApiClient = _communicationFactory(tenant);
response = communicationApiClient.JctConfigurationService.GetApns();
}
catch (HttpException e)
{
...
}
return response?.Apns ?? new List<ApnResponse>();
}
通过以下测试:
private Mock<ICommunicationApiFacade> _communicationApiFacade;
[SetUp]
public void SetUp()
{
_fixture = new Fixture()
.Customize(new AutoMoqCustomization());
_communicationApiFacade = _fixture.Freeze<Mock<ICommunicationApiFacade>>();
}
[Test]
public void RunJctTests_WhenJctIsInAPrivateNetwork_ShouldReturnAPassedTest()
{
// Arrange
var jctApn = _fixture.Create<string>();
var message = _fixture.Build<JctLoggedIn>()
.With(x => x.ApnFromDevice, jctApn)
.Create();
var response = _fixture.Build<ApnResponse>()
.With(x => x.IsPrivateApn, true)
.With(x => x.ApnName, jctApn).Create();
_communicationApiFacade.Setup(x => x.TryGetApns(string.Empty))
.Returns(new List<ApnResponse> { response });
var subject = _fixture.Create<NetworkProviderTestRunner>();
// Act
var result = subject.Execute(message);
// Assert
Assert.That(result.Result, Is.True);
}
这是 NetworkProviderTestRunner class:
private readonly ICommunicationApiFacade _communicationApi;
public NetworkProviderTestRunner(ICommunicationApiFacade communicationApi)
{
_communicationApi = communicationApi;
}
public JctTest Execute(JctLoggedIn message)
{
var apns = _communicationApi.TryGetApns(message.Tenant);
var jctApn = apns.FirstOrDefault(x => x.ApnName == message.ApnFromDevice);
if (jctApn != null)
{
var privateApn = apns.FirstOrDefault(x => x.PublicApnId.Equals(jctApn.Id));
if (privateApn != null || jctApn.IsPrivateApn)
return new JctTest { Result = true };
}
return new JctTest { Result = false };
}
JctLoggedIn class:
public class JctLoggedIn : Message
{
public string Imei { get; set; }
public string SimCardIdFromDevice { get; set; }
public string SimCardIdFromStorage { get; set; }
public string ApnFromDevice { get; set; }
public string ApnFromStorage { get; set; }
public string FirmwareFromDevice { get; set; }
public int DeviceTypeFromStorage { get; set; }
public int SerialNumber { get; set; }
}
但出于某种原因,我总是得到一个空列表。我试图在 SetUp 中填充列表并在那里定义输出,但我总是一样。有帮助吗?
这一行
_communicationApiFacade.Setup(x => x.TryGetApns(string.Empty))
.Returns(new List<ApnResponse> { response });
告诉模拟 return 包含响应的列表,当调用 TryGetApns 时租户参数为空字符串。
此行创建消息后 message.Tenant 的值是多少:
var message = _fixture.Build<JctLoggedIn>()
.With(x => x.ApnFromDevice, jctApn)
.Create();
如果不是 string.empty,您的模拟将不会 return 响应列表。
替换
var response = _fixture.Build<ApnResponse>()
.With(x => x.IsPrivateApn, true)
.With(x => x.ApnName, jctApn).Create();
和
var response = _fixture.Build<ApnResponse>()
.With(x => x.Tenant, String.Empty)
.With(x => x.IsPrivateApn, true)
.With(x => x.ApnName, jctApn).Create();
如果租户是可写的。
如果 属性 是可写的,AutoFixture 将为租户创建一个具有非空值的对象,而无需明确设置您想要的内容。
虽然您可以在构建 message
对象时明确省略 Tenant
属性,但您也可以将 Mock 设置更改为:
_communicationApiFacade.Setup(x => x.TryGetApns(message.Tenant))
.Returns(new List<ApnResponse> { response });