I got some business logic code I want to test.
At the moment I only know how to write unit test on logic code that hasn't other dependencies.
Can anyone point me in the good direction of how to test for example this function and maybe give an example?
Is the only way to test this an integration test or do I have 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 Repository & rhino mocks):
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;
}
This worked perfectly thanks all!
Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. This testing methodology is done during the development process by the software developers and sometimes QA staff.
To get started, select a method, a type, or a namespace in the code editor in the project you want to test, right-click, and then choose Create Unit Tests. The Create Unit Tests dialog opens where you can configure how you want the tests to be created.
From my perspective...
Your logic is not be able to test if you interact with database via DataBaseEntities context(ProductionEntities) directly. because your logic that depend on ProductionEntities.
I would recommend you to follow Repository Pattern for your data access layer. You would be able to make you code to be testability logic. The pattern will help you to inject data access layer from logic.
I also would like to recommend you to follow dependency injection pattern. This pattern will help you to do unit test your code easier. You will be able to use mock framework like Rhino mock to help you on unit testing.
This doesn't look like a piece of business logic as much as a piece of data access.
You could stub out your ProductionEntities using dependency injection via an interface, with a lambda to ensure that your "using" works in 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 overkill. At some point, you do need to access your data. What @pongsathon-keng has said is fair - using a repository pattern will help - but I think this is code that belongs in the repository. It seems simple enough that I wouldn't worry about breaking up the dependency on the data.
You can either use an integration test just to test this piece, or you could just test the whole system and make sure that this part of it plays nicely with the other parts.
It may help if you think of each test just as an example of how to you use your code. It's not really there to test your code as much as to help you explore what it should and shouldn't do, and how other people can use it. If it only makes sense to use the code when it's integrated, write an integration test. Otherwise, you can use the pattern above to inject a mock.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With