最小起订量设置优先

时间:2019-03-28 09:42:26

标签: c# moq

我已经遍历了所有先前的答案,但都没有解决我的问题。

让我说我有以下代码:

public interface ISomeInterface
{
    int SomeMethod(int a, string b);
}

现在我有一个通用的模拟类,它为上述方法定义了一些默认行为

public class CommonMock
{
    public Mock<ISomeInterface> MockInterface = new Mock<ISomeInterface>().Setup(x => x.SomeMethod(It.IsAny<int>(), It.IsAny<string>())).Returns(It.IsAny<int>());
}

我需要一些默认行为,因为我有很多需要默认行为的测试用例。

但是在某些特定的测试场景中,在完全独立的测试类中,我需要能够在测试某些特定的测试用例时返回不同的值。

如下所示:

[Test]
public void TestSomeMethodSpecific()
{
    var commonMock = new CommonMock();
    commonMock.MockInterface.Setup(x => x.SomeMethod(It.IsAny<int>(), It.IsAny<string>())).Returns(42);

    // Do some test based on the new return value
}

我该如何实现?

下面我附上一些实际代码:

通用设置

public class MockStore
{
    public Mock<IProcessHandler> ProcessHandler = new Mock<IProcessHandler>();
    ProcessHandler.Setup(x => x.GetCurrentProcessRunId()).Returns(It.IsAny<int>());
}

测试类中的替代设置

var mockstore = new MockStore();
mockStore.ProcessHandler.Setup(x => x.GetCurrentProcessRunId()).Returns(25);

几乎有50到70个这样的模拟,每个模拟都从简单​​类型返回复杂类。

2 个答案:

答案 0 :(得分:0)

那行得通吗?如果您在方法上创建后续设置,并且该设置是无条件的(对参数没有限制),则它将删除该方法的所有先前设置。

您可以看到my answer here that explains it with the source code

如果您希望有条件的多个安装程序根据参数返回不同的值,请参阅How to setup a method twice for different parameters with mock

没有看到完整的代码,也许您已经在使用条件安装程序。在这种情况下,顺序很重要,也许您是用更通用的设置覆盖了较早的设置。

答案 1 :(得分:0)

您可以拥有可以随时修改的全局模拟对象。例如,我有这个:

[TestClass]
public class StoreServiceTest
{
    Mock<IAccess> mockAccess;
    Mock<IAccess> mockAccessNoData;
    Mock<IDataReader> mockReader;
    Mock<IDataReader> mockReaderNoData;
    Mock<IStoreService> mockStoreService;

然后在TestInitiailize上,我Setup的默认实现如下:

mockReader = new Mock<IDataReader>();
mockReader.Setup(m => m.IsDBNull(It.IsAny<int>())).Returns(false);
mockReader.Setup(m => m.GetString(It.IsAny<int>())).Returns("stub");
mockReader.Setup(m => m.GetBoolean(It.IsAny<int>())).Returns(true);
mockReader.Setup(m => m.GetInt32(It.IsAny<int>())).Returns(32);
mockReader.SetupSequence(m => m.Read()).Returns(true).Returns(false); // setup sequence to avoid infinite loop

mockAccess = new Mock<IAccess>();
mockAccess.Setup(m => m.ReadData(It.IsAny<string>(), It.IsAny<object[]>())).Returns(mockReader.Object);

mockReaderNoData = new Mock<IDataReader>();
mockReaderNoData.Setup(m => m.Read()).Returns(false);

mockAccessNoData = new Mock<IAccess>();
mockAccessNoData.Setup(m => m.ReadData(It.IsAny<string>(), It.IsAny<object[]>())).Returns(mockReaderNoData.Object);

mockStoreService = new Mock<IStoreService>(); 

现在,对于默认类型的测试,我要做的就是通过mockReader.Object,它应该具有默认实现,因为每个测试都以TestInitialize开头,然后对于特殊情况,说我想要返回"sub"的{​​{1}}方法的"stub"而不是IDataReader的方法,我可以这样做:

GetString()

希望有帮助!