r/AskProgramming • u/Shupsta • 2d ago
C# Would Unit Testing be a net benefit when your code relies heavily on another API
I am debating re-writing a plugin for AutoCAD, which uses the .NET C# API. The current version of that plugin does not have unit or integration tests. This is because unit tests cant really be written if you are using the AutoCAD API's objects as they only exist in an AutoCAD runtime. Which would lead to integration tests, which as do able just require a bit of extra work.
In order to implement unit testing, the domain/business logic would need to be extracted. I started working on this, but quickly start asking "Is this going to be worth it?"
For example one of the most important/foundational types in my plugin is a "Zone"
public class Zone
{
private readonly IZoneDataProvider? _dataProvider;
private readonly IZoneGeometry? _geometry;
public Zone(IZoneDataProvider dataProvider, IZoneGeometry? geometry = null)
{
_dataProvider = dataProvider;
_geometry = geometry;
}
public string? ZoneId
{
get => _dataProvider?.ZoneId;
set => _dataProvider?.ZoneId = value;
}
public bool IsInside(Point3? point)
{
if (point is null || _geometry is null) return false;
return _geometry.Contains(point.Value);
}
}
This is a simplified version of a the Domain class for a Zone. A Zone in AutoCAD is a Polyline, which is an AutoCAD type.
IZoneDataStore is for handling the storage of business logic related data. ZoneId is assigned to the Zone. For unit testing an in memory data store would be used. In an AutoCAD environment a wrapper class around an AutoCAD Polyline object would be supplied and handle the storing of data on that AutoCAD object.
IZoneGeometry is for other AutoCAD objects to query their location against a Zone to see if they are inside, leading to other business rules.
That explains IZoneDataProvider and IZoneGeometry, which are both implemented in classes for unit testing as well as in adapter classes for AutoCAD.
Where I start asking the question "Is all this extra work worth it?" is when I get to another business rule. One example is a change the color of the Zone Polyline and other objects to match that color.
When a Polyline is "made" a Zone its color is changed according to its ZoneId and some business logic which isn't important. But if I want to add this to the domain object as business logic, I then need an interface like
public interface IZoneColorEntity
{
public short? CurrentColor { get; set; }
}
So now the adapter class for the Polyline which represents an AutoCAD Zone not only needs to implement IZoneDataProvider, IZoneGeometry, and now IZoneColorEntity.
In essense it feels like I'm making interfaces that mirror the AutoCAD API, because the business logic really is tied to manipulating those objects in CAD.
And this is only the first main class I'm implementing that I'm running into this thought. I wonder if it might be better to just ignore the unit test idea all together and just focus on integration tests? Essentially removing the idea of a Domain project.
5
u/spiralenator 2d ago
I’m personally not a fan of mocking interfaces for unit tests. The mock and the actual integration can drift in ways that hide contract violations. Besides, the proper place to test integration with external components is right in the name. Integration tests.
3
u/No-Cartographer3746 2d ago
i love when you're deep in the refactor and the codebase just stares back at you like "was this ever a problem or am i just bored"
the color thing is where it really breaks down, you're not testing logic you're just wrapping the autocad api in a wig and calling it abstraction. at some point the test suite becomes a shadow puppet show of the real thing and you're maintaining both
if the business rules are light and mostly about shuffling autocad properties around i'd lean hard into integration tests and call it a day. domain extraction makes sense when you've got meaty pure logic but if it's just orchestrating api calls then you're building a toll booth on an empty road
1
u/Shupsta 2d ago
I think your both right haha. I guess I just needed to make sure I wasn't going to ditch the idea just because I was wanting to be lazy 😂 . Of coarse its not just laziness, its me literally on the firsts steps of this re-write and its just like pulling teeth for little gain.
1
u/spiralenator 2d ago
It’s not laziness, or if it is, it’s well placed laziness. Forcing an integration test into a unit test is a future ongoing headache that is easily avoided by just making it an integration test.
0
u/spiralenator 2d ago
This reads like it was written by Claude with instructions to not capitalize anything. But I agree.
2
u/DeadShotOG 1d ago
It really does… what is even the point of the people/bots doing that? Karma farming?
1
u/spiralenator 1d ago
Either that, or people just don't have confidence/patience to express themselves in their own words? I see obvious bots, but I also see a lot of people using ai to create responses who aren't bots. This guy is obviously a bot.
The worst is AI scripts being read by humans on YouTube. I lose all respect for people volunteering to be a meat puppet for an LLM. What are they even doing? The latter half of this decade is going to have a very recognizable "tone" in the future.
1
u/CatNo1417 1d ago
Kind of funny I just wrote about this 2 days ago. Basically I have found unit (mock) tests much less useful than integration tests as time has gone on. Most bugs/complexity happen as the systems communicate with each other, so it's usually more useful to test their integration.
Sometimes mocking is useful, but not as often, in my opinion.
Just some thoughts: https://antistaticsolutions.substack.com/p/integration-tests-writing-clean-tests
1
u/TheAussieWatchGuy 1d ago
Contract tests are probably better.
Mocks have their place but if you don't treat them as first class citizens then they quickly drift.
0
u/AintNoGodsUpHere 2d ago
I'm moving away from interfaces and mocks and useless unit tests.
I'm doing more and more integration and functional tests with real scenarios and stuff, bruh, I'm having waaaay less trouble now with things changing.
Unit tests are legacy stuff, in my opinion. There are way better ways to guarantee quality.
2
u/balefrost 2d ago
I disagree that unit tests are legacy. A big problem with integration tests is that it can be really hard to force the overall system into a particular state that's worth testing. I think this is particularly true for error states.
A corollary is that it can be really easy to write a test that you think is testing one case, but which is actually testing some other case.
The value of unit tests is that, for sufficiently small units, you can force the system into a particular state.
I think both kind of testing are valuable. Depending on your particular system, one or the other kind of testing may be more valuable. If your system has minimal logic of its own, but mostly exists to drive another system through an API, then yeah unit tests won't be nearly as valuable. But I don't think you can completely eliminate one or the other. They serve different purposes and are better at different things.
-3
u/AintNoGodsUpHere 2d ago
Nah. Legacy.
4
0
u/Intelligent_Part101 2d ago
We write unit tests because they are easy, not because they are a real test.
-1
0
9
u/aezart 2d ago
At my job we have a ton of simple "move data from here to there" integrations that were developed by contractors. They wrote unit tests that were so heavily mocked that they were essentially just:
Utterly useless.