简体   繁体   English

如何在Moq中模拟字符串类

[英]How to mock string class in Moq

I have a Test method which is like this 我有一个像这样的测试方法

[Test]
public void VerifyRedirectedTempCodeWithAnEmptyString()
{
    var mockStringLength = new Mock<string>();
    mockStringLength.Setup(x => x.Length).Returns(0);
    Boolean returnValue = VerifyRedirectedTempCode(mockStringLength.Object);
    Assert.AreEqual(returnValue, false);
}

There is no compilation error, but when I run this test its giving System.NotSupportedException : Type to mock must be an interface or an abstract or non-sealed class. 没有编译错误,但是当我运行此测试时,它给出了System.NotSupportedException:要模拟的类型必须是接口或抽象或非密封类。 here is my actual method 这是我的实际方法

    public virtual Boolean VerifyRedirectedTempCode(string tempAuthCode)
    {
        if (tempAuthCode != null && tempAuthCode.Length > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

So, how to mock the string.length property.So that even in future if they update the length method it should not affect my test method. 因此,如何模拟string.length属性,以便即使将来他们更新length方法也不会影响我的测试方法。 How to mock? 如何嘲笑?

You don't need to mock the string length here. 您无需在此处模拟字符串长度。 The method you're testing expects an integer, so just pass it an integer! 您要测试的方法需要一个整数,因此只需将其传递给整数即可! If you really want you can pass it string.Empty.Length , in case this changes in a future version of the framework. 如果确实需要,可以将其传递给string.Empty.Length ,以防在将来的框架版本中发生更改。

With a unit test, you're testing the behaviour of a method given its inputs and the state of its dependencies. 使用单元测试,您可以根据输入和依赖状态来测试方法的行为。 If your method takes an int and returns a bool then all you need to do to test it is to pass in an int . 如果您的方法接受一个int并返回一个bool那么测试它所需要做的就是传递一个int The method shouldn't care where it came from. 该方法不应该在意它的来源。 This is a matter of separation of concerns. 这是关注点分离的问题。


Following your update, given your method takes a string you just need to test its behaviour given different string inputs. 更新之后,给定您的方法使用一个string您只需要在给定不同字符串输入的情况下测试其行为即可。 At least null , string.Empty , and some valid string . 至少为nullstring.Empty和一些有效的string

You can't expect your test to never fail as you change your method's implementation. 您不能期望更改方法的实现会导致测试永不失败。 In fact, you should change your test first so it DOES fail, the change your code so the tests pass, then refactor. 实际上,您应该先更改测试以使其失败,然后更改代码以使测试通过,然后进行重构。 This is called the red, green, refactor cycle. 这称为红色,绿色重构周期。


It seems like your validator is probably part of a larger piece of work and maybe what you're really interested in testing is how the rest of your code behaves given the different potential validation results. 似乎您的验证器可能是更大工作的一部分,也许您真正感兴趣的是在给定潜在验证结果不同的情况下,其余代码的行为方式。 In this case, I would recommend that you extract your validation logic into a separate class whose interface you can then mock. 在这种情况下,我建议您将验证逻辑提取到一个单独的类中,然后可以模拟该类的接口。 Supply the validator as a dependency to the code that needs it. 提供验证器作为对需要它的代码的依赖。 Then, in your tests you can supply a mock validator that behaves in a predetermined way. 然后,在测试中,您可以提供以预定方式运行的模拟验证器。 That way you can write your tests without worrying that a future change to the validator logic will break them. 这样,您可以编写测试,而不必担心将来对验证器逻辑的更改会破坏它们。 This seems to be the essence of your question. 这似乎是您问题的本质。

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

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