Reputation: 11721
My unit testing method is as follows
[Test]
public void TrackPublicationChangesOnCDSTest()
{
//Arrange
// objDiskDeliveryBO = new DiskDeliveryBO();
//Act
var actualResult = objDiskDeliveryBO.TrackPublicationChangesOnCDS();
//Assert
var expectedZipName = 0;
Assert.AreEqual(expectedZipName, actualResult);
}
The Actual method TrackPublicationChangesOnCDS
in BO is as follows
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;
}
}
I want to mock the method call
DiskDeliveryDAO().TrackPublicationChangesOnCDS(pubRecordsExceptToday);
How Can I achieve this ? I am not getting enough examples online . I am using Moq library. Can someone help ?
Upvotes: 3
Views: 15463
Reputation: 246998
Current code is too tightly coupled to implementation concerns to make it easy to test in isolation.
Reviewing the method under test revealed the following dependencies that were abstracted
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);
}
Their respective implementations would wrap/implement the desired functionality in production.
The abstractions would now allow the method under test to be refactored as below.
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;
}
}
}
Note how not much has actually changed in the method itself apart from changing the tight coupling of new DiskDeliveryDAO()
to the inject dependency.
Now the class is more flexible and can be tested in isolation where you have complete control of the dependencies and their behavior.
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);
}
}
Check Moq Quickstart for more on how to setup the desired behavior on the mocks.
Upvotes: 3
Reputation: 5255
var mockDeliveryDao = new Mock<DiskDeliveryDAO>();
mockDeliveryDao.Setup(o=>o.TrackPublicationChangesOnCDS(It.IsAny<List<string>>()).Returns(1);//or whatever flag you want
Now you need to pass the deliveryDao as a parameter to the constructor. Use Dependency Injection instead of creating a new DeliveryDao() object in the code.
That way your code will read something like:
resultFlag = _diskDeliveryDao.TrackPublicationChangesOnCDS(pubRecordsExceptToday);
While your constructor would be setting the _diskDeliveryDao member variable.
Upvotes: 0
Reputation: 51
It is not possible to mock DiskDeliveryDAO().TrackPublicationChangesOnCDS(pubRecordsExceptToday) using moq as it is directly newing the object using concrete class. It is possible only when we have the concrete class implement an interface and DiskDeliveryDAO object should be injected through DiskDeliveryBO's constructor.
Upvotes: 1