如何设置模拟以返回任务<ilist <t >>

时间:2019-03-20 01:40:57

标签: c# unit-testing moq xunit

早安,

我正在为我的课程方法编写单元测试,这是我的课程:

public class GetClientDetails {
    public async Task<IList<Channels>> GetChannelsAsync() {
        try {


            var channel = new Channels();
            var channels = new List<Channels>();

                    await _client.CreateSessionAsync().ConfigureAwait(false);
                    channel = await _client.GetChannelsAsync();

                    channels.Add(channel);
                }
            }

            return channels;
        } catch (Exception ex) {
            return null;
        }
    }
}

我正在使用
xunit 2.4.0
最小起订量4.10.1

这是我的单元测试:

public class GetDetailsTest {
    Mock<GetClientDetails> getDdetails = new Mock<GetClientDetails>();
    [Fact]
    public void Test1() {
        IList<Channels> expected = new List<Channels>() { new Channels{{channelvalue}};
        //Having issue on this line
        getDdetails.Setup(x => x.GetChannelsAsync()).ReturnsAsync(expected);
        var results = getDdetails.Object;
        Assert.NotNull(results);
    }
}

这是错误:

程序“ [67384] dotnet.exe”已退出,代码为0(0x0)。
程序“ [67384] dotnet.exe:程序跟踪”已退出,代码为0(0x0)。

我可以知道如何正确设置模拟任务类吗?

致谢

2 个答案:

答案 0 :(得分:1)

由于最初的问题还不完整,所以在显示您应该做的测试预期的类时,我不得不做一些假设。

让我们假设您有一堂课,看起来像这样

public class GetClientDetails {
    private readonly IOurApiService _client;

    public GetClientDetails(IOurApiService ourService) {
        _client = ourService;
    }

    public async Task<IList<Channels>> GetChannelsAsync() {
        try {
            await _client.CreateSessionAsync().ConfigureAwait(false);
            var channel = await _client.GetChannelsAsync();
            var channels = new List<Channels>();
            channels.Add(channel);
            return channels;
        } catch (Exception ex) {
            return null;
        }
    }
}

请注意主题类的显式依赖项IOurApiService

为了单独对GetChannelsAsync进行单元测试,您需要模拟/添加类的依赖关系,以使被测方法在执行时表现出预期的效果。

例如

public class GetDetailsTest {
    [Fact]
    public async Task GetChannelsAsync_Should_Return_Channels() {
        //Arrange
        var channel = new Channels{
            //{channelvalue}
        };
        IList<Channels> expected = new List<Channels>() { 
            channel
        };
        var serviceMock = new Mock<IOurApiService>();
        serviceMock.Setup(_ => _.CreateSessionAsync()).Returns(Task.CompletedTask);
        serviceMock.Setup(_ => _.GetChannelsAsync()).ReturnsAsync(channel);

        var subject = new GetClientDetails(serviceMock.Object);

        //Act
        var actual = await subject.GetChannelsAsync();

        //Assert
        Assert.Equal(expected, actual);
    }
}

答案 1 :(得分:0)

这是我得到的最新错误: 在非虚拟成员(在VB中可重写)上的无效设置:rep => rep.GetChannelsAsync()

研究后的问题是:Moq无法模拟非虚拟方法和密封类

有关详细信息:Why am I getting an Exception with the message "Invalid setup on a non-virtual (overridable in VB) member..."?

所以我要做的是使我的班级成为虚拟班级:

public virtual async Task<IList<Channels>> GetChannelsAsync()