如何在“真实”方法中调用模拟方法时使用参数?

时间:2018-08-31 16:50:35

标签: c# lambda moq

我正在模拟具有此签名的方法:

-----------child1--child2----------
-----------child3-----------------

...,我想使用已经在测试类中定义的方法来进行定量。也就是说,我不想要使用lambda表达式。

如何像使用lambda表达式那样将发送给模拟方法的参数传递给“真实”方法?


调用lambda表达式(参数与调用时发送的参数匹配)

也就是说,如果这就是我用lambda编写的方式...

public async Task<string> Upsert(Preferences prefs, string id)

...我在调用中返回了_mockDataAdapater .Setup(x => x.Upsert(It.IsAny<Preferences>(), It.IsAny<string>())) .Returns((Preferences p, string id) => { return Task.FromResult(id); // see how I can use ^^^^ the `id` param here? }); 参数中的值。

id

这就是我想要的。

调用“真实”功能(总是“垃圾邮件”)

如何在设置时指定参数public async void testMe() { var output = await _mockDataAdapater.Object.Upsert(new Preferences(), "hello"); System.Diagnostics.Debug.WriteLine(output); // <<< "hello" in this case. } p的值,并且仍然使用此语法?

id

总是// This is what I want to use instead of a lambda expression. private async Task<string> _upsertMock(Preferences prefs, string id) { return await Task.Run(() => { return id; }); } //... public MyClassConstructor() { // Set up mock objects... _mockDataAdapater .Setup(x => x.Upsert(It.IsAny<Preferences>(), It.IsAny<string>())) .Returns(_upsertMock(new Preferences(), "spam")); // Both params are hard coded! ^^^^^^^^^^^^^ // // (Rather, if I don't insert hard-coded params here, I can't // get things to build. How do I hook up to the It.IsAnys?) } 调用中返回“垃圾邮件”。最低起订量!

testMe

要清楚,我知道为什么我总是得到public async void testMe() { var output = await _mockDataAdapater.Object.Upsert(new Preferences(), "hello"); System.Diagnostics.Debug.WriteLine(output); // <<< now always "spam" } 。那讲得通。但是很臭。

我的问题是在第二种情况下如何重新使用“真实”方法调用中的参数?


这行得通,但感觉不对

我可以wrap my function in another function ...

"spam"

包装是访问_mockDataAdapater .Setup(x => x.Upsert(It.IsAny<Preferences>(), It.IsAny<string>())) .Returns((Preferences p, string id) => { return _upsertMock(p, id); }); p的唯一方法吗?

1 个答案:

答案 0 :(得分:1)

我尝试了以下证明,并且按预期工作

[TestClass]
public class MyTestClass {
    public class Preferences {

    }
    public interface IInterface {
        Task<string> Upsert(Preferences prefs, string id);
    }

    public Task<string> _upsertMock(Preferences prefs, string id) {
        return Task.Run(() => {
            return id;
        });
    }

    [Test]
    public async Task MyTestMethod() {

        var mock = new Mock<IInterface>();
        mock
            .Setup(_ => _.Upsert(It.IsAny<Preferences>(), It.IsAny<string>()))
            .Returns((Func<Preferences, string, Task<string>>)_upsertMock);

        var expected = "123";

        var actual = await mock.Object.Upsert(null, expected);

        actual.Should().Be(expected);
    }
}

请注意代表的投射

.Returns((Func<Preferences, string, Task<string>>)_upsertMock);

以便在设置过程中使用正确的.Returns重载。