使用Moq Start()方法不断调整空对象

问题描述 投票:0回答:1

我在弄清楚为什么我无法测试我的driver变量时遇到了麻烦,当我调用null时,它不断返回Start()。我基本上想访问该变量并对其进行测试。

我目前无法通过的测试:

[TestMethod]
public void Start_Default_IsChrome2()
{
    var dummyManager = new Mock<IRemoteDriver>();
    var mockDriver = new Mock<IWebDriver>();
    dummyManager.Setup(x => x.CreateRemoteWebDriver(new ChromeOptions()))
                .Returns(It.IsAny<RemoteWebDriver>());
    var session = new SauceSession(dummyManager.Object);
    //The Start() keeps returning a null object
    var driver = session.Start();
    var capabilities = driver.Capabilities;
    capabilities.GetCapability("browserName").Should().Be("chrome");
}

要嘲笑的依赖性

public interface IRemoteDriver
{
    IWebDriver CreateRemoteWebDriver(ChromeOptions chromeOptions);
}

被测对象

public SauceSession(IRemoteDriver driverManager)
{
    remoteDriverManager = driverManager;
}



public RemoteWebDriver Start()
{
    sauceUserName = Environment.GetEnvironmentVariable("SAUCE_USERNAME", EnvironmentVariableTarget.User);
    sauceAccessKey = Environment.GetEnvironmentVariable("SAUCE_ACCESS_KEY", EnvironmentVariableTarget.User);
    sauceOptions = new Dictionary<string, object>
    {
        ["username"] = sauceUserName,
        ["accessKey"] = sauceAccessKey
    };

    var chromeOptions = new ChromeOptions
    {
        BrowserVersion = "latest",
        PlatformName = "Windows 10",
        UseSpecCompliantProtocol = true
    };
    chromeOptions.AddAdditionalCapability("sauce:options", sauceOptions, true);
    //This keeps returning a null
    return (RemoteWebDriver)remoteDriverManager.CreateRemoteWebDriver(chromeOptions);
}

如果有帮助,则具体实现可以正常工作,并且该测试如下所示:

    [TestMethod]
    public void Start_Default_IsChrome()
    {
        var session = new SauceSession();
        var driver = session.Start();
        var capabilities = ((RemoteWebDriver)driver).Capabilities;
        capabilities.GetCapability("browserName").Should().Be("chrome");
    }

除了我在这里设置的对象以外,其他所有东西都相同:

    public SauceSession()
    {
        remoteDriverManager = new ConcreteRemoteWebDriver();
    }

class ConcreteRemoteWebDriver : IRemoteDriver
{
    public IWebDriver CreateRemoteWebDriver(ChromeOptions chromeOptions)
    {
        return new RemoteWebDriver(new Uri("https://ondemand.saucelabs.com/wd/hub"),
            chromeOptions.ToCapabilities(), TimeSpan.FromSeconds(600));
    }
}

这里是RemoteWebDriver:

public class RemoteWebDriver : IWebDriver, ISearchContext, IDisposable, IJavaScriptExecutor, IFindsById, IFindsByClassName, IFindsByLinkText, IFindsByName, IFindsByTagName, IFindsByXPath, IFindsByPartialLinkText, IFindsByCssSelector, ITakesScreenshot, IHasInputDevices, IHasCapabilities, IHasWebStorage, IHasLocationContext, IHasApplicationCache, IAllowsFileDetection, IHasSessionId, IActionExecutor
c# unit-testing mocking moq
1个回答
2
投票

您未正确完成设置。

dummyManager.Setup(x => x.CreateRemoteWebDriver(new ChromeOptions()))
            .Returns(It.IsAny<RemoteWebDriver>());

这里两件事:

您正在精确匹配new ChromeOptions()的一个实例。在确定要返回哪个对象时,Moq将检查传递给CreateRemoteWebDriver的参数是否与设置中提供的参数相同。

new ChromeOptions
{
     BrowserVersion = "latest",
     PlatformName = "Windows 10",
     UseSpecCompliantProtocol = true
};

new ChromeOptions()

将得出相等的结果,表示此设置将不匹配。

您可能只是想像这样使用It.IsAny<ChromeOptions>()

dummyManager.Setup(x => x.CreateRemoteWebDriver(It.IsAny<ChromeOptions>()))

第二个问题是您的返回值显式为null。It.IsAny<T>()始终返回T的默认值。 It方法都仅用于Setup表达式内的参数匹配。如果在设置表达式之外使用它们,则将只获取通用参数的默认值,在这种情况下,该默认值为空值。 Moq库没有使这种不正确的用法成为大声的错误消息,这是很可惜的。因此,您需要提供RemoteWebDriver的实际实例作为返回值。 (或者,如果您可以将实现与特定的具体类型分离,则可以返回实现IWebDriver的东西。)

该值可能是另一个Mock对象,但是它必须是您提前创建的,或者可以通过Return回调创建的。

正确的设置可能类似于:

var mockDriver = new Mock<RemoteWebDriver>();
dummyManager.Setup(x => x.CreateRemoteWebDriver(It.IsAny<ChromeOptions>()))
            .Returns(mockDriver.Object); //This could throw an exception if RemoteWebDriver needs arguments.

一个小警告是,您将实际上创建一个RemoteWebDriver实例作为结果。如果这样做有不利的副作用(例如创建镶边窗口),则需要考虑将策略从使用特定的具体类型更改为某些接口或抽象类。如果这样做,则安装程序可能类似于以下内容:

var mockDriver = new Mock<IWebDriver>();
dummyManager.Setup(x => x.CreateRemoteWebDriver(It.IsAny<ChromeOptions>()))
            .Returns(mockDriver.Object);
热门问题
推荐问题
最新问题