c# - 如何使用最小起订量模拟方法调用

标签 c# mocking nunit moq

我的单元测试方法如下

[Test]
public void TrackPublicationChangesOnCDSTest()
{
    //Arrange
    // objDiskDeliveryBO = new DiskDeliveryBO();            

    //Act
    var actualResult = objDiskDeliveryBO.TrackPublicationChangesOnCDS();

    //Assert 
    var expectedZipName = 0;
    Assert.AreEqual(expectedZipName, actualResult);
}

BO中的实际方法TrackPublicationChangesOnCDS如下

public int TrackPublicationChangesOnCDS()
{

    var resultFlag = -1;

    try
    {

        string pubUpdateFileCDSPath = CommonCalls.PubUpdateFileCDSPath;
        string pubUpdateFileLocalPath = CommonCalls.PubUpdateFileLocalPath;


        if (File.Exists(pubUpdateFileCDSPath))
            File.Copy(pubUpdateFileCDSPath, pubUpdateFileLocalPath, true);

        if (File.Exists(pubUpdateFileLocalPath))
        {

            string[] pubRecords = File.ReadAllLines(pubUpdateFileLocalPath);

            var pubRecordsExceptToday = pubRecords.Where(p => !p.Trim().EndsWith(DateTime.Now.ToString("dd/MM/yy"))).ToList();

            resultFlag = new DiskDeliveryDAO().TrackPublicationChangesOnCDS(pubRecordsExceptToday);

            File.WriteAllText(pubUpdateFileLocalPath, string.Empty);

            string[] pubRecordsCDS = File.ReadAllLines(pubUpdateFileCDSPath);
            var pubRecordsTodayCDS = pubRecordsCDS.Where(p => p.Trim().EndsWith(DateTime.Now.ToString("dd/MM/yy"))).ToList();
            File.WriteAllLines(pubUpdateFileCDSPath, pubRecordsTodayCDS);

        }

        return resultFlag;
    }
    catch (Exception)
    {

        return -1;
    }

}

我想模拟方法调用 DiskDeliveryDAO().TrackPublicationChangesOnCDS(pubRecordsExceptToday);

我怎样才能做到这一点?我在网上没有得到足够的例子。我正在使用最小起订量库。有人可以帮忙吗?

最佳答案

当前代码与实现问题的耦合过于紧密,无法轻松进行隔离测试。

查看被测方法揭示了以下被抽象的依赖性

public interface ICommonCalls {
    string PubUpdateFileCDSPath { get; }
    string PubUpdateFileLocalPath { get; }
}

public interface IDiskDeliveryDAO {
    int TrackPublicationChangesOnCDS(List<string> pubRecordsExceptToday);
}

public interface IFileSystem {
    bool Exists(string path);
    void Copy(string sourceFilePath, string destinationFilePath, bool overwrite);
    string[] ReadAllLines(string path);
    void WriteAllText(string path, string contents);
    void WriteAllLines(string path, IEnumerable<string> contents);
}

它们各自的实现将包装/实现生产中所需的功能。

抽象现在允许被测方法重构如下。

public class DiskDeliveryBO {
    readonly ICommonCalls CommonCalls;
    readonly IDiskDeliveryDAO diskDeliveryDAO;
    readonly IFileSystem File;

    public DiskDeliveryBO(ICommonCalls CommonCalls, IDiskDeliveryDAO diskDeliveryDAO, IFileSystem File) {
        this.CommonCalls = CommonCalls;
        this.diskDeliveryDAO = diskDeliveryDAO;
        this.File = File;
    }

    public int TrackPublicationChangesOnCDS() {

        var resultFlag = -1;

        try {

            string pubUpdateFileCDSPath = CommonCalls.PubUpdateFileCDSPath;
            string pubUpdateFileLocalPath = CommonCalls.PubUpdateFileLocalPath;


            if (File.Exists(pubUpdateFileCDSPath))
                File.Copy(pubUpdateFileCDSPath, pubUpdateFileLocalPath, true);

            if (File.Exists(pubUpdateFileLocalPath)) {

                string[] pubRecords = File.ReadAllLines(pubUpdateFileLocalPath);

                var pubRecordsExceptToday = pubRecords.Where(p => !p.Trim().EndsWith(DateTime.Now.ToString("dd/MM/yy"))).ToList();

                resultFlag = diskDeliveryDAO.TrackPublicationChangesOnCDS(pubRecordsExceptToday);

                File.WriteAllText(pubUpdateFileLocalPath, string.Empty);

                string[] pubRecordsCDS = File.ReadAllLines(pubUpdateFileCDSPath);
                var pubRecordsTodayCDS = pubRecordsCDS.Where(p => p.Trim().EndsWith(DateTime.Now.ToString("dd/MM/yy"))).ToList();
                File.WriteAllLines(pubUpdateFileCDSPath, pubRecordsTodayCDS);
            }

            return resultFlag;
        } catch (Exception) {

            return -1;
        }
    }
}

请注意,除了更改 new DiskDeliveryDAO() 与注入(inject)依赖项的紧密耦合之外,方法本身实际上并没有太大变化。

现在该类更加灵活,可以在您完全控制依赖项及其行为的情况下进行隔离测试。

public class DiskDeliveryBOTests {
    [Test]
    public void TrackPublicationChangesOnCDSTest() {
        //Arrange
        var expected = 0;
        var commonMock = new Mock<ICommonCalls>();
        //...Setup commonMock desired behavior

        var daoMock = new Mock<IDiskDeliveryDAO>();
        //...Setup daoMock desired behavior
        daoMock
            .Setup(_ => _.TrackPublicationChangesOnCDS(It.IsAny<List<string>>())
            .Returns(expected);

        var fileMock = new Mock<IFileSystem>();
        //...Setup fileMock desired behavior

        var objDiskDeliveryBO = new DiskDeliveryBO(commonMock.Object, daoMock.Object, fileMock.Object);

        //Act
        var actualResult = objDiskDeliveryBO.TrackPublicationChangesOnCDS();

        //Assert             
        Assert.AreEqual(expected, actualResult);
    }
}

检查 Moq Quickstart有关如何在模拟上设置所需行为的更多信息。

关于c# - 如何使用最小起订量模拟方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43649228/

相关文章:

c# - C# 的 GetOpt 库

unit-testing - 如何模拟 HttpClientCertificate?

.net - nUnit - 忽略 DLL 的 GAC 副本

javascript - 在被测试的方法中模拟一个函数

tfs - 如何从VS2010用msbuild运行nunit

c# - Unity 和 NUnit

c# - 您可以在 UWP 中的 C# 代码中使用 C++ DLL 吗?

c# - 在没有安装Word的情况下以编程方式将DOCX转换为PDF?

c# - MVC 配置种子方法未插入指定的主键

ruby - Rspec 与系统交互