简体   繁体   English

如何验证Moq是否已调用方法?

[英]How to verify that a method was called with Moq?

I'm trying to validate that SetFirefoxOptions() is called when I call GetFirefoxDriver() . 我试图验证SetFirefoxOptions()是当我打电话叫GetFirefoxDriver() But for whatever reason, Moq keeps telling me that it wasn't called. 但是无论出于什么原因,Moq一直告诉我没有被调用。 What am I doing wrong? 我究竟做错了什么?

Here's my test: 这是我的测试:

[TestMethod]
public void ShouldSetFirefoxOptions()
{
    var stubCapabilities = new Mock<SauceCaps>().Object;
    var mockManager = new Mock<DriverManager>();
    mockManager.Setup(
        m => m.GetFirefoxDriver(stubCapabilities)).
        Returns(It.IsAny<IWebDriver>());

    mockManager.Verify(
        m => m.SetFirefoxOptions(stubCapabilities));
}

DriverManager.cs: DriverManager.cs:

public class DriverManager : IDriverManager
{
    public virtual Dictionary<string, object> SauceOptions { get; private set; }    

    public DriverManager()
    {
    }

    public virtual IWebDriver GetFirefoxDriver(SauceCaps sauceCaps)
    {
        var browserOptions = SetFirefoxOptions(sauceCaps);

        return new RemoteWebDriver(new Uri("https://ondemand.saucelabs.com/wd/hub"),
            browserOptions.ToCapabilities(), TimeSpan.FromSeconds(600));
    }

    public virtual FirefoxOptions SetFirefoxOptions(SauceCaps sauceCaps)
    {
        return new FirefoxOptions
        {
            BrowserVersion = sauceCaps.BrowserVersion, 
            PlatformName = sauceCaps.Os
        };
    }
}

The problem with your code is that it is unclear what is your System Under Test . 您的代码的问题在于,您不清楚被测系统是什么。 You are mocking and testing the same class at the same time. 您正在同时模拟和测试相同的类。 Although it is technicaly possible using moq (using CallBase) it is in principle wrong approach. 尽管使用moq (使用CallBase)在技术上是可行的,但原则上是错误的方法。

The one possibility is to extract SetFirefoxOptions into separate interface and inject it into the DriverManager , eg 一种可能性是将SetFirefoxOptions提取到单独的interface并将其注入到DriverManager ,例如

public interface IFirefoxOptionCreator
{
    FirefoxOptions SetFirefoxOptions(SauceCaps sauceCaps);
}

public DeviceManager(IFirefoxOptionCreator optionCreator)
{
    _optionCreator = optionCreator;
}

public virtual IWebDriver GetFirefoxDriver(SauceCaps sauceCaps)
{
    var browserOptions = _optionCreator.SetFirefoxOptions(sauceCaps);

    return new RemoteWebDriver(new Uri("https://ondemand.saucelabs.com/wd/hub"),
        browserOptions.ToCapabilities(), TimeSpan.FromSeconds(600));
}

then you could easily verify is interface method was called within your unit tests: 那么您可以轻松地验证在单元测试中是否调用了接口方法:

[TestMethod]
public void ShouldSetFirefoxOptions()
{
    // Arrange
    var stubCapabilities = new Mock<SauceCaps>().Object;    
    var optionCreatorMock = new Mock<IFirefoxOptionCreator>();
    optionCreatorMock.Setup(m => m.SetFirefoxOptions(It.IsAny<SauceCaps>()))
                     .Returns(new FirefoxOptions());
    var sut = new DriverManager();    

    // Act
    _ = sut.GetFirefoxDriver(stubCapabilities);

    // Assert
    optionCreatorMock.Verify(m => m.SetFirefoxOptions(stubCapabilities));
}

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

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