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

时间:2015-04-21 21:15:47

标签: c# asp.net-mvc unit-testing tdd moq

我有两个实现接口的类,但是这两个类都有一个参数传递给构造函数,以确定应用程序需要哪个类。当我创建一个可用的实例时,我尝试在(AvailablityRepoData)类上测试一个(GetAvailablity)方法我得到了非虚方法的错误。如果有人能指出我正确的方向,我真的很感激。

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);

1 个答案:

答案 0 :(得分:1)

正如评论中已经说过的那样,您已经发布了错误信息的代码并不清楚。如果我将其复制并直接进入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,这是具体类。由于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);
}

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

作为一般经验法则,你不应该嘲笑被测系统。如果你发现自己正在为系统创建一个模拟器,那么你正在测试它,这是一个很好的迹象,表明你在一个课程中有很多功能和/或你试图测试错误的东西...

作为一个助手,您可能希望查看类似builder pattern的内容来创建不同的存储库,而不是将类型传递给每个存储库的构造函数,就像您似乎建议的那样。