简体   繁体   English

模拟IList的单元测试方法

[英]Unit test method mocking IList

I'm trying to mock the following method TryGetApns : 我正在尝试模拟以下方法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>();
    }

with the following test: 通过以下测试:

    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);
    }

and this is the NetworkProviderTestRunner class: 这是NetworkProviderTestRunner类:

    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: JctLoggedIn类:

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; }
}

but for some reason I always get back an empty list. 但出于某种原因,我总是得到一个空列表。 I've tried to populate the list in the SetUp and also defining the output there but I's always the same. 我试图在SetUp中填充列表并在那里定义输出,但我总是一样。 Any help? 有帮助吗?

While you could explicitly omit the Tenant property when building the message object, you could also change the Mock setup to this: 虽然您可以在构建message对象时明确省略Tenant属性,但您也可以将Mock设置更改为:

_communicationApiFacade.Setup(x => x.TryGetApns(message.Tenant))
    .Returns(new List<ApnResponse> { response });

This line 这条线

_communicationApiFacade.Setup(x => x.TryGetApns(string.Empty))
        .Returns(new List<ApnResponse> { response });

is telling the mock to return the list containing response when TryGetApns is called with an empty string for the tenant parameter. 告诉mock在使用tenant参数的空字符串调用TryGetApns时返回包含响应的列表。

What is the value of message.Tenant after message is created by this line: 在此行创建消息后,message.Tenant的值是什么:

var message = _fixture.Build<JctLoggedIn>()
        .With(x => x.ApnFromDevice, jctApn)
        .Create();

If it is not string.empty, your mock will not return the reponse list. 如果它不是string.empty,则mock不会返回响应列表。

Replace 更换

var response = _fixture.Build<ApnResponse>()
            .With(x => x.IsPrivateApn, true)
            .With(x => x.ApnName, jctApn).Create();

with

var response = _fixture.Build<ApnResponse>()
            .With(x => x.Tenant, String.Empty)
            .With(x => x.IsPrivateApn, true)
            .With(x => x.ApnName, jctApn).Create();

if Tenant is writable. 如果租客是可写的。

If the property is writable, AutoFixture will create an object with non-empty value for Tenant without explicitly setting up what you want. 如果属性是可写的,则AutoFixture将为Tenant创建一个非空值的对象,而无需显式设置您想要的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM