Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
230 views
in Technique[技术] by (71.8m points)

c# - Moq - Updating Reference Parameter Inside Callback Not Working

I'm trying to unit test a method where a function is called in a loop. One of the parameters supplied to the method is a List<string>, declared outside the loop, that should be updated by each call that it is passed to.

I've been trying to mock this behaviour using some examples that I found on SO that involve updating the parameter inside of a Callback(), but this hasn't worked for me as expected.

Here is a short-hand example of the problem I'm having:

Method

public async Task DoSomething() {
    var strings = new List<string>();

    for(i = 0; i < 2; i++) {
        var response = await _responder.GetResponse(i, strings);
        //method adds a new string into the collection on each call
    }
}

So to test this, I would need to mock both method calls, knowing that the string collection would be empty on one and contain one element on the other...

Test

public async Task TestDoSomething() {
    var strings = new List<string>();

    var mock = new Mock<Responder>();
    mock.Setup(x => x.GetResponse(0, strings)) //mocks first iteration of loop
        .ReturnsAsync(new Response())
        .Callback<int, List<string>>((number, stringCollection) => {
            stringCollection = new List<string> {"addedString"}; //this is where the problem occurs
            strings = stringCollection;
        });

    mock.Setup(x => x.GetResponse(1, strings)) //mocks second iteration of loop
        .ReturnsAsync(new Response());

    //...
}

So at the point where I try to update the collection of strings inside the callback, studio highlights the parameter and gives me the warning The value passed to the method is never used because it is overwritten in the method body before being read.

The test fails because the setups are not matched, and trying to debug causes the test to crash and drop out.

Can anyone point me in the right direction here? Between the warning message and the fact that all the other examples of this stuff just use Returns rather than ReturnsAsync, I would guess that it's to do with the timing of updating the parameter.

Thanks in advance!

question from:https://stackoverflow.com/questions/66064958/moq-updating-reference-parameter-inside-callback-not-working

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Not sure what exactly you want to test the method call or that values added to the collection. But if you want to test that method was called, you can use Verify function like this -

mock.Verify(mock => mock.GetResponse(It.IsAny<int>(), strings), Times.Exactly(2));

PS. You should use It.IsAny<int>() cause first param obtain index from loop SO _responder.GetResponse(0, strings) calls only once and so on.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...