两个 类 的单元测试继承一个接口

Unit Test for two classes inherit an Interface

我有两个 class 实现了一个接口,但是两个 class 都有一个参数传递给构造函数来确定 class 应用程序需要什么。我正在尝试在 (AvailablityRepoData) class 上测试一个 (GetAvailablity) 方法,当我创建 AvailablityRepoData 的实例时,我收到非虚拟方法的错误。如果有人能指出正确的方向,我将不胜感激。

public interface IAvailablityRepo
   {
     string  GetAvailablity(Availablity availablity);
}
public class AvailablityRepoData: IAvailablityRepo
{

    public AvailablityRepoData(string websetting) {
    }
    public string GetAvailablity(Availablity availablity) {
        return "Data";
    }
}

public class AvailablityRepoWeb:IAvailablityRepo
{
    public AvailablityRepoWeb(string DataSetting) {
    }
    public string GetAvailablity(Availablity availablity) {
        return "Web";
    }
}

public class Availablity
{
    public virtual string Id {
        get;
        set;
    }
    public virtual string  Status {
        get;
        set;
    }
}

        var a = new Availablity() { Id = "111", Status = "A"};
        Mock<IAvailablityRepo> mockRepo = new Mock<IAvailablityRepo>();
        Mock<IAvailablityRepo> RepoData = new Mock<IAvailablityRepo>();
        RepoData.Setup(x => x.GetAvailablity(It.IsAny<Availablity>  ())).Returns("pass");
        var result = RepoData.Object.GetAvailablity(a);

如评论中所述,从您发布的代码中不清楚您的错误是什么。如果我将它直接复制并粘贴到 visual studio 中(将测试代码包装在测试中),测试会顺利通过。我要建议,当您遇到错误时,您的测试代码实际上更接近于此:

[TestMethod]
public void TestMethod1() {
    var a = new Availablity() { Id = "111", Status = "A" };
    Mock<IAvailablityRepo> mockRepo = new Mock<IAvailablityRepo>();
    Mock<AvailablityRepoData> RepoData = new Mock<AvailablityRepoData>();
    RepoData.Setup(x => x.GetAvailablity(It.IsAny<Availablity>())).Returns("pass");
    var result = RepoData.Object.GetAvailablity(a);
}

当测试为 运行:

时,这会导致错误
System.NotSupportedException:Invalid setup on a non-virtual (overridable in VB) member:
                             x => x.GetAvailablity(It.IsAny<Availablity>())

此测试与您的原始测试之间的区别在于,我已将 Mocked 类型从接口 IAvailabilityRepo 更改为 AvailabilityRepoData,即具体的 class。由于 Moq 仅支持模拟接口/虚拟方法,因此它自然会感到沮丧。

正如@prgmtc 所提到的,您目前的测试并没有真正测试任何东西。

使用您当前的代码,实际上看起来您根本不需要使用 Mocks。这样的测试可能更合适:

[TestMethod]
public void TestDataRepoReturnsDataAvailability() {
    var someImportantSetting = "thisShouldBeSomethingMeaningful";
    var availability = new Availablity() { Id = "111", Status = "A" };
    var sut = new AvailablityRepoData(someImportantSetting);

    var returnedAvailability = sut.GetAvailablity(availability);

    Assert.AreEqual("Data", returnedAvailability);
}

假设您的实际代码更复杂,传递到您的数据存储库的字符串可能需要更有意义...

根据一般经验,您不应该模拟被测系统。如果您发现自己正在为正在测试的系统创建一个模拟,这很好地表明您在一个 class and/or 中拥有很多功能,您正在尝试测试错误的东西......

顺便说一句,您可能想研究 builder pattern 之类的东西来创建不同的存储库,而不是像您建议的那样将类型传递给每个存储库的构造函数。