-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a utilities class to help write the boiler plate recording code a bit easier #83
Comments
Interesting idea, @CableZa. Can you tell me more? Without knowing how the interface would look, it's unclear what benefit it brings. Can you show a before/after? Alternatively, if it's as little work for you, a PR showing the same would be fine. |
This only really matters when one needs to record numerous fakes/dependencies, but the utility class helps a lot with some common test setup code:
I don't have the before, but here is the after: using (var testDoubleUtilities = new TestDoubleUtilities(recordingsBasePath, testClassName, testName))
{
var fakeDependency = testDoubleUtilities.CreateSelfInitializingTestDouble(createRealDependency);
var sut = CreateSUT(fakeDependency);
//ACT
var result = await sut.ExecuteSomeMethodAsync();
//ASSERT
if (result is OkNegotiatedContentResult<Response>)
{
var response = ((OkNegotiatedContentResult<ConcreteResponseClass>)result).Content;
Assert.IsTrue(response.SomeBoolParam);
Assert.AreEqual(500m, response.SomeOtherParam);
}
} Without this, the boiler plate code is needed to create the folder structure for recording test doubles: var basePath = Path.Combine(testRecordingsBasePath, testClassName, testName);
if (!Directory.Exists(basePath))
{
Directory.CreateDirectory(basePath);
}
this.BasePath = basePath; One would need to create the repo and fake for each dependency that needs faking, and remember to dispose it (below its being added to a list for later disposal) var typeName = typeof(T).Name;
var recordedFilePath = Path.Combine(this.BasePath, typeName + ".json");
var fakeRepo = new JsonFileRecordedCallRepository(recordedFilePath);
var selfInitializingFake = SelfInitializingFake<T>.For(createRealService, fakeRepo);
this.fakesToDispose.Add(selfInitializingFake.Dispose);
return selfInitializingFake; |
The interface for TestDoubleUtilities is public TestDoubleUtilities(string testRecordingsBasePath, string testClassName, string testName){}
public SelfInitializingFake<T> CreateSelfInitializingTestDouble<T>(Func<T> createRealService) where T : class{} |
I see, thanks. That's interesting. I've never worried about the boilerplate for creating a directory for the files to live in. I just make the directory by hand once and after that, once I commit a file, the directory's known to be there forever. Are you doing something different so you have uncertainty around the directory's presence? I can see how having multiple services be disposed might be handy, but am not really sure how the experience is that much better than just using a And if I understand things right, the |
Not at all, I'm just trying to make it easier to follow a convention for test recordings :-)
My thinking was around trying to keep the test code cleaner/easier to follow especially in cases where 4-5 classes/dependencies are being recorded in one test.
Correct, although I suppose it could take the recorder type in as a parameter somehow for flexibility?
Interesting point - what other basis for repositories do you see possible for this? Databases? Web? |
Makes sense. I'm not sure it's up to the library to pick a convention, especially when it dictates serializer type and path structure. Although I guess why not? There's nothing inherently wrong with providing a convention. People don't have to use it. But I'm just not seeing that it makes things that much easier to use, so far. To me, the complexity is nearly the same, with more code to maintain in the library.
Yeah, it would typically be 5 using (var testDoubleUtilities = new TestDoubleUtilities(recordingsBasePath, testClassName, testName))
{
var fakeDependency1 = testDoubleUtilities.CreateSelfInitializingTestDouble(createRealDependency1);
var fakeDependency2 = testDoubleUtilities.CreateSelfInitializingTestDouble(createRealDependency2);
var fakeDependency3 = testDoubleUtilities.CreateSelfInitializingTestDouble(createRealDependency3);
var fakeDependency4 = testDoubleUtilities.CreateSelfInitializingTestDouble(createRealDependency4);
var fakeDependency5 = testDoubleUtilities.CreateSelfInitializingTestDouble(createRealDependency5);
var sut = CreateSUT(fakeDependency1, fakeDependency2, fakeDependency3, fakeDependency4, fakeDependency5);
…
} and rewrote as original (I haven't run this, but I think it's about right) using (var fakeDependency1 = new SelfInitializingFake<IService1>.For(createRealDependency1, new XmlFileRecordedCallRepository("base/testclass/testname/service1.xml")))
using (var fakeDependency2 = new SelfInitializingFake<IService2>.For(createRealDependency2, new XmlFileRecordedCallRepository("base/testclass/testname/service2.xml")))
using (var fakeDependency3 = new SelfInitializingFake<IService3>.For(createRealDependency3, new XmlFileRecordedCallRepository("base/testclass/testname/service3.xml")))
using (var fakeDependency4 = new SelfInitializingFake<IService4>.For(createRealDependency4, new XmlFileRecordedCallRepository("base/testclass/testname/service4.xml")))
using (var fakeDependency5 = new SelfInitializingFake<IService5>.For(createRealDependency5, new XmlFileRecordedCallRepository("base/testclass/testname/service5.xml")))
{
var sut = CreateSUT(fakeDependency1, fakeDependency2, fakeDependency3, fakeDependency4, fakeDependency5);
…
} Aside from the fact that the 5 In the
Adding a recorder type is appealing. Of course, there'd need to be a consistent interface for the creation method in that case. If we assume file-based, then a single string in the constructor would work.
My guess, if any non-file repo is ever implemented, would be database. But I suppose some sort of web-based storage is possible. |
Awesome thanks very much @blairconrad! |
Split from #79
While it's easy enough to contain this code in your own methods, it would be nice to have a utils type class that will help jump start users new to this library.
For this I propose adding an Utilties class.
The text was updated successfully, but these errors were encountered: