How to write a solid unit test for this business logic code?

I have a business logic code that I want to verify.
At the moment, I only know how to write unit test by logical code, which has no other dependencies.

Can someone point me in the right direction, how to check, for example, this function and maybe give an example?

Is the only way to test this integration test or do I need to use mock / stub?

/// <summary> /// Gets the scan face file by a MemberID /// </summary> /// <param name="MemberID">The ID of a member</param> /// <returns>A scan face file in byte array format</returns> public byte[] GetScanFileFaceByMemberID(int MemberID) { byte[] scanFileFace; using (ProductionEntities entityContext = new ProductionEntities()) { scanFileFace = (from scan in entityContext.tblScan where scan.MEMBERID == MemberID select scan.scanFileFace).Single(); } return scanFileFace; } 

CHANGES (I implemented the repository and rhinos):

BL:

 public byte[] GetScanFileFaceByMemberID(int MemberID) { byte[] scanFileFace; var query = Repository.GetAll<tblScan>().Where(bl => bl.MEMBERID == MemberID).Single(); scanFileFace = query.scanFileFace; return scanFileFace; } 

Unit test:

 [TestMethod] public void GetScanFileFace_ExistingScan_ReturnByteArray() { //Make testScan List<tblScan> testScan = PrepareTestDataScan(); //Arrange KlantenBL klantenBL = new KlantenBL(); klantenBL.Repository = MockRepository.GenerateMock<IRepository>(); klantenBL.Repository.Stub(bl => bl.GetAll<tblScan>()).IgnoreArguments().Return(testScan); //Act var result = klantenBL.GetScanFileFaceByMemberID(2); //assert Assert.AreEqual(result.GetType().Name, "Byte[]"); Assert.AreEqual(result.Length, 10); } //Prepare some testData private List<tblScan> PrepareTestDataScan() { List<tblScan> scans = new List<tblScan>(); //Declare some variables byte[] byteFile = new byte[4]; byte[] byteFile10 = new byte[10]; DateTime date = new DateTime(2012,01,01); scans.Add(new tblScan { SCANID = 1, MEMBERID = 1, scanFileFace = byteFile, Hair = byteFile, scanFileAvatar = byteFile, scanFileMeasurements = byteFile, scanDate = date }); scans.Add(new tblScan { SCANID = 2, MEMBERID = 2, scanFileFace = byteFile10, Hair = byteFile, scanFileAvatar = byteFile, scanFileMeasurements = byteFile, scanDate = date }); scans.Add(new tblScan { SCANID = 3, MEMBERID = 3, scanFileFace = byteFile, Hair = byteFile, scanFileAvatar = byteFile, scanFileMeasurements = byteFile, scanDate = date }); return scans; } 

Repository:

 public IList<T> GetAll<T>() { DZine_IStyling_ProductionEntities context = GetObjectContext(); IList<T> list = context .CreateQuery<T>( "[" + typeof(T).Name + "]") .ToList(); ReleaseObjectContextIfNotReused(); return list; } public IList<T> GetAll<T>(Func<T, bool> expression) { DZine_IStyling_ProductionEntities context = GetObjectContext(); IList<T> list = context .CreateQuery<T>( "[" + typeof(T).Name + "]") .Where(expression) .ToList(); ReleaseObjectContextIfNotReused(); return list; } 

It worked great thanks to everyone!

+4
source share
2 answers

From my point of view...

Your logic will not be able to test if you interact directly with the database through the DataBaseEntities (ProductionEntities) context. because your logic depends on ProductionEntities.

I would recommend you follow the repository pattern for your data access level. You could make your code validation logic. The template will help you implement the level of access to data from the logic.

I would also recommend that you follow the dependency injection pattern. This template will help you make unit test your code easier. You can use a mockup framework like Rhino to help you with unit testing.

+3
source

This is not like part of the business logic, nor part of the data access.

You can drown out your ProductionEntities using dependency injection through the interface, with a lambda, to ensure that your "use" works the same way:

 // Use this in real code public class MyClass() : MyClass(() => new ProductionEntities()) { } // Use this in your test public class MyClass(Func<IHaveEntities> entities) { _entities = entitites; } public byte[] GetScanFileFaceByMemberID(int MemberID) { byte[] scanFileFace; using (IHaveEntities entityContext = _entities()) { scanFileFace = (from scan in entityContext.tblScan where scan.MEMBERID == MemberID select scan.scanFileFace).Single(); } return scanFileFace; } 

However, I think this will be redundant. At some point you need to access your data. What @ pongsathon-keng said is true - using a repository template will help, but I think this is code that belongs to the repository. It seems simple enough that I will not worry about breaking the data dependency.

You can use the integration test only to test this part, or you can just test the whole system and make sure that this part goes well with other parts.

This can help if you think of each test as an example of how you use your code. This is actually not the case to test your code, to help you explore what it should and should not do, and how other people can use it. If it makes sense to use code when it is integrated, write an integration test. Otherwise, you can use the template above to enter the layout.

+2
source

Source: https://habr.com/ru/post/1397737/


All Articles