What governs when [BeforeScenario] is run in SpecFlow? - c#

I've recently started on an existing project that uses SpecFlow.
I've added a method with [BeforeScenario] in BaseSteps.cs that does some logging. BaseSteps.cs doesn't have a [Binding] attribute on its class, but the derived classes do have [Binding].
However, an example.feature can use steps from differentDerivedSteps.cs classes. In these case the [BeforeScenario] is being called multiple times in a single scenario from that feature.
Why is this happening? What is calling the BeforeScenario multiple times for a single scenario?

Some code might help identify the issues, but it might be that the derived steps classes all have the method [BeforeScenario] (as they inherit it) and so specflow is calling once for each derived class.
In Specflow its usually not necessary to get involved with any inheritance as all steps are global and accessible from anywhere, so just move your [BeforeScenario]into its own class, whack a [Binding] attribute on it and Specflow will find it an use it.

Avoid using inheritance in your Steps classes - I've found it sometimes causes weird "multiple matching bindings found"
First answer here explains why inheritance causes confusion with Specflow steps:
https://stackoverflow.com/a/15508054/2213092
Without code it's difficult to determine why it's calling that specific BeforeScenario multiple times though. If you're still troubleshooting this, you can put a breakpoint on the BeforeScenario method, and look down the call stack to see where it's being fired from.

Related

Allow Helper Services to Only be Called From One Service in .NET Core

I have the following structure:
PdfGenerationService (umbrella)
PdfGenerationDataService (gets data for umbrella)
PdfGenerationFunctionService (calls Azure function "microservice" to gen PDF)
PdfAzureSaveService (saves PDF to storage)
The problem is that other devs and myself have the tendency to try to use one of the "supporting" services outside of the "umbrella" service, when they really have no stand-alone functionality. We remember this too late, and by the time we do, we need to refactor.
e.g. we call the supporting PdfAzureSaveService from a controller, and then remember that we have the PdfGenerationService that does all of this for us without getting into the details and need to refactor.
I want to limit the helper services to only be usable within the umbrella PdfGenerationService. Access levels don't seem to help me with that, unless I want to make an arbitrary parent class that all 4 inherit from and then make the helper services protected. The other alternative is to put all the helpers into private methods on the "umbrella" service, that really violates DRY imo.
tl;dr: Is there some way to mark methods as only accessible from one service?
edit: JHBonarius made a good point that I should mention - these services ARE exposed via standard .NET Core DI. There is no real reason that they couldn't be static (and avoiding DI entirely), but that seems to still leave the problem of other services/controllers just importing the namespace and using the static services where they shouldn't.
So your scenario is that you have a class which requires three other classes:
public PdfGenerationService(
PdfGenerationDataService s1,
PdfGenerationFunctionService s2,
PdfAzureSaveService s3
)
And you register those classes with DI:
services.AddTransient<PdfGenerationService>();
services.AddTransient<PdfGenerationDataService>();
services.AddTransient<PdfGenerationFunctionService>();
services.AddTransient<PdfAzureSaveService>();
And now you want to prevent developers from writing, in their own code:
public Foo(PdfGenerationFunctionService s1)
Because they're supposed to use PdfGenerationService as a dependency?
Then move all those classes into their own library, and make the three dependencies of the first service internal. Now other code can't refer to them by their name, so it can't ask for them to be injected.
Or write an analyzer that checks that other code doesn't use those classes. Or mark them obsolete, suppressing the warning in PdfGenerationService's constructor. Or throw an exception in the three other class's methods if the method one stack frame lower doesn't originate from PdfGenerationService (but don't).

Why is [TestClass]'s constructor called multiple times for each [TestMethod]?

In case of you have multiple test method on a test class. Class's constructor is going to run multiple times. How we can explain this overload?
From my understanding of MSTest, the test class gets instantiated for each [TestMethod]. I'm guessing you are attempting to run configuration code before any of the tests are ran. If that's the case I'd recommend you:
A) update your question to explain what it is exactly you would like to accomplish
B) make use of the [ClassInitialize] attribute to mark a method to be ran once and only once before any of the class's tests are ran
What Does ClassInitialize Do
ClassInitialize is one of the many attributes available when using MSTest to write unit tests in C#. The more common ones include TestClass, TestMethod, and TestInitialize. This one indicates that the method should be ran once before running any of the methods marked with TestMethod. There's another attribute that goes hand-in-hand with it called ClassCleanup which gets ran after all of the test methods get ran.
You can read more details about these and more attributes at learn.microsoft.com

Inheriting test methods across projects

I'm trying to have a test class for the VS test framework, that is derived from another test class and inherits all its test methods (so that each appears twice). This was suggested in a comment on another ticket.
When this is done within the same project, it works fine. When done across projects, everything compiles fine but the new tests don't show up.
In this minimal solution, the problem is demonstrated. Two projects, in each we derive from the same base class in the first project. But the new (duplicate) tests only show up for the same-project child class.
I suspect something is optimized away in someway, but don't know what or how top debug this. I tried adding a dummy TestMethod to the second-project test class, just so that something must happen with the class - then only this test method shows, without the derived methods. Suggestions would be appreciated.

Testing private members with a SelfTest() method

I have a bunch of classes that wrap DB queries. I want to be able to test-run each query, and verify the result, returned to private members of my class. The perhaps barbaric idea that sprung to mind was to give my query wrappers a public SelfTest() method, visible to XUnit with a [Fact] attribute. As such, my test method would have access to the internals of the class and could verify in detail the outcome of the DB request.
Are there unhappy consequences I should be aware of? I would be adding a public method to my DB wrapper classes, but the method would do no damage. I would be making my application directly 'consumable' by XUnit, rather than having my tests in a separate project as I'm used to, but this seems harmless, no?
Adding the SelfTest() methods to your production code will have no direct impact on the functionality. But your notion that this is kind of
'babaric' is caused by the violation of several principles we know as Clean Code.
Just to name a few points:
First of all this will violate the Single Responsibilty Principle. Beside the functionality itsself the class has the responsibility to test itsself.
More code and more complexity is added to the class. Who wants to read all the test code if someone is just interesting in understanding the functionality ?
You add additional dependencies to your production code (XUnit in this case) and the assemblies will be part of your shipped product.
But what is an alternative approach ?
Just making all methods and properties public for the sake of testing is not suitable as well. But with the InternalsVisibleTo annotation in the assembly.cs you can give the test project assembly the right to access internal methods and properties of the assembly to test.
Example:
Add in the assembly.cs of MyAssembly the line
[assembly:InternalsVisibleTo("MyAssembly.UnitTests")]
Then in MyAssembly.UnitTests internal methods can be used.

How do I find what methods are called from a C# class method - NOT at run time

I have a C# class that has far too much code in, and I want to refactor it. What I would like to do is start with all the public methods, and build a tree for each one, showing which other methods in the class are called from it, and then which are called from the child one, and so on.
This will enable me to see which private methods belong solely to one public method, which are shared and so on.
Note that I DON'T want to do this at run time, I want to be able to look at a class, either directly at the .cs file, or using reflection on the compiled DLL.
I know I can use reflection on the compiled DLL to get the methods, but I can't find any way of finding out which methods are called by other methods in the class.
Anyone any ideas? Again, this is NOT a run time issue, it's purely to build a reusable utility to help refactor an oversized class. There are quite a few in the solution I'm working on, so the code woudl be used over and over again.
Visual Studio 2010 has action "View Call Hierarchy" where you can see all places in your solution where your code is invoked.
From my experience this static analysis may be somewhat lacking, for example method could be called dynamically using Reflection, through Data Binding, through Dependency Injection Container, etc.
Also, that may be bit off topic, and not applicable in your case, but I find a good way to find dead code for component is to have a suite of integration tests. Then you can run code coverage, and visually see what paths of code are never executed.

Categories

Resources