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

我在弄清楚为什么我无法测试我的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
VIQVIQ 回答:使用Moq,Start()方法会不断调整空对象

您的设置不正确。

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对象,但它必须是您提前创建的对象,或者可以通过Returns回调创建的对象。

正确的设置可能类似于:

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);
本文链接:https://www.f2er.com/3131368.html

大家都在问