我已经遍历了所有先前的答案,但都没有解决我的问题。
让我说我有以下代码:
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个这样的模拟,每个模拟都从简单类型返回复杂类。
答案 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()
希望有帮助!