It felt wrong but I had to rape myself with a huge purple dildo


  • Dupa

    So, I did a horrible thing yesterday and the sad thing is, I still don't see a way to do it better.

    I'm writing tests for a library and the goal is to have 100% test coverage, or rather what well done 100% test coverage indicates -- knowledge when someone you don't trust changes something. Unfortunately, the rationale is strong.

    And then there's this class that is a steaming pile of VB.NET shit. It's one class, although there should be like 10 of them instead. One of the many things it does is, it takes a dataset with around 50 columns and validates it by calling internal validate methods which are created for all basic data types: decimal, double, integer, Boolean plus a few others specific to this shit-ass construct.

    And then all of those methods are called from one huge-ass validator method and what I need to do is I need to ensure that the correct value is passed to the correct function. Normally, I could take care of this using moq -- mock validators, verify that they were called with correct parameters. The thing is, it would still need a lot of preparation, but it would at least look nicer.

    What I had to do instead is I had to subclass the fucker and create collections for each method, then I needed to override the methods and instead of calling base I had to add parameters as a new element to their respective collections. For a dozen of methods or so. Whatever.

    What I did next is I prepared a dataset generator: I had the column names so I created the columns and filled rows with random strings. Then in the test methods I extracted the values from the columns I knew were passed to each function (along with other parameters) to a collection and then verified that the collection in the subclass was was of the same size and contained the same values in the same order.

    The caveat was: since the class I was subclassing was already a subclass, it defined all methods as protected overridable, since this is what the parent abstract class had to do. But then there was this one fucking method specific to the subclass marked private, so I had to change it to protected overridable just for benefit of my fucking tests.

    The question is, could this be done in a better way, given the situation? I know I could rewrite the class but: I don't know VB well enough to feel comfortable with it and there's no time for that, and it's a pretty important piece of code to our product. So, given that splitting this fucker into smaller classes was not an option, a rewrite was not an option and only small changes here and there were acceptable: was there a better way?

    I'm using NUnit and Moq. Tests are written in C#.


  • Discourse touched me in a no-no place

    @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    And then there's this class that is a steaming pile of VB.­NET shit. It's one class, although there should be like 10 of them instead.

    So it's a God Class? Where the god in question is Moloch, requiring child sacrifice…



  • @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    The question is, could this be done in a better way, given the situation?

    Yeah; rewrite the library.

    @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    I know I could rewrite the class but: I don't know VB well enough to feel comfortable with it and there's no time for that, and it's a pretty important piece of code to our product. So, given that splitting this fucker into smaller classes was not an option,

    Sounds like you need to get together with your manager and determine your priorities. You already know the correct solution; you're just not doing it because you "there's no time". Well, then the tests don't get written until there is time.

    It's not a technical problem preventing you from doing this, it's a people problem. You need to be given more time to complete the task. There's no Visual Studio plug-in you can install to get more time.

    (And, BTW, what's the point of having 100% test coverage of that huge class in a language nobody knows that nobody has time to rewrite? It just means when someone does rewrite it, they'll have to rewrite all the tests too. So you're making the actual task here [ensuring quality code] more difficult. The goal is unit tests isn't just to say "we have 100% coverage and we're done forever!")



  • If I was testing a class like that in Java using Mockito, I think I might be able to do it with a Spy instead of a Mock. Does Moq have something similar?


  • Dupa

    @blakeyrat said in It felt wrong but I had to rape myself with a huge purple dildo:

    Yeah; rewrite the library.

    We would very much like to do that, but we can't.

    @blakeyrat said in It felt wrong but I had to rape myself with a huge purple dildo:

    (And, BTW, what's the point of having 100% test coverage of that huge class in a language nobody knows that nobody has time to rewrite? It just means when someone does rewrite it, they'll have to rewrite all the tests too. So you're making the actual task here [ensuring quality code] more difficult. The goal is unit tests isn't just to say "we have 100% coverage and we're done forever!")

    The goal is, we're nuget-izing a library that's being used in many different projects in many different ways. What we want is to be sure, that its behaviour doesn't change when someone edits it in the future, since there will be many more people interested in that then.

    So yeah, what we're doing is a step in the right direction, but sure, it doesn't fix the problem.

    Also: our product is mainly VB.NET with newer components being written in C#.


  • Dupa

    @CarrieVS said in It felt wrong but I had to rape myself with a huge purple dildo:

    Does Moq have something similar?

    I'm not sure what Spy is, but having a quick look it seems to be a way to override only chosen methods, so no, I don't think so.

    It looks pretty cool, though.

    With such a tool I could probably go by without subclassing. I'd simply override the pertinent methods and then verify that they were called x times. Is there a way to check which parameters they were called with?


  • Dupa

    @CarrieVS said in It felt wrong but I had to rape myself with a huge purple dildo:

    If I was testing a class like that in Java using Mockito, I think I might be able to do it with a Spy instead of a Mock. Does Moq have something similar?

    Well, having a fresh look now, it looks like it might be possible with Moq, too. I'm not sure if it would work with private/protected methods, though. :/



  • @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    I'm not sure what Spy is, but having a quick look it seems to be a way to override only chosen methods, so no, I don't think so.
    It looks pretty cool, though.
    With such a tool I could probably go by without subclassing. I'd simply override the pertinent methods and then verify that they were called x times. Is there a way to check which parameters they were called with?

    From that description, it should already be part of Fakes, which you should be able to use if everyone is on VS enterprise, and so is your build server. You can override methods with the delegate of your choice with Fakes.



  • @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    I'm not sure what Spy is, but having a quick look it seems to be a way to override only chosen methods, so no, I don't think so.
    ... With such a tool I could probably go by without subclassing. I'd simply override the pertinent methods and then verify that they were called x times.

    That's what I thought you were asking for.

    Is there a way to check which parameters they were called with?

    With Mockito, verifying a method call to a spy or a mock requires you to specify the arguments it should be called with, though it provides matchers whenever you don't need to check. There's also ArgumentCaptor in case you need to check something more complex about a parameter than what it's equal to. Does Moq not allow that?

    @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    I'm not sure if it would work with private/protected methods, though. :/

    I thought you could with Mockito but on further inspection it appears Spy can only handle private methods if they are static. Not sure about protected. Again, though, that's Mockito and I don't know anything about Moq.



  • @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    We would very much like to do that, but we can't.

    Look; you're focused on the wrong thing. What's the goal of your adding tests? Is it just to check off "100% test coverage" on some consultant's Excel spreadsheet, or is it to increase the quality of your code?

    If the former, then yes, do whatever.

    If the latter, then rewriting that class is advancing your goal.

    If the only obstacle to not doing it is "not enough time", well, then get more time. You obviously under-estimated the project. No biggie; it happens all the time.

    @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    The goal is, we're nuget-izing a library that's being used in many different projects in many different ways. What we want is to be sure, that its behaviour doesn't change when someone edits it in the future, since there will be many more people interested in that then.

    Ok. I guess.

    @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    So yeah, what we're doing is a step in the right direction, but sure, it doesn't fix the problem.

    No it doesn't, and it might even make the problem more difficult to fix in the future.

    Just fix the problem now.

    @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    Also: our product is mainly VB.NET with newer components being written in C#.

    Then there ought to be plenty of people around with enough VB.Net experience to fix that library.


  • Dupa

    @CarrieVS well, it turns out moq can do that, too. Only it can't handle private methods, I suspect it works its magic through inheritance. However, all this can be ultimately done the right way, so a happy rewrite awaits me tomorrow.

    Thanks for your help.


  • Dupa

    @blakeyrat well, you're missing the point. The point of the project is not to rewrite or fix the code, it was to unify it between projects and versions of our software. There's one superclass with a lot of implementations there, our code holds a few of them, others have their. Before the code was scattered (and probably fixed) between projects, now it'll be in one place. That was the goal.

    As much as I'd love to do the rewrite, it's not possible.


  • kills Dumbledore

    Can't you use reflection to overwrite the access modifier of a method? I've never done it myself but I think I remember seeing stuff mention it



  • @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    @blakeyrat well, you're missing the point.

    I disagree; you yourself have said multiple times in this thread that the code needs to be fixed.

    But whatever, you obviously don't want my advice so I'll go away.


  • Dupa

    @blakeyrat said in It felt wrong but I had to rape myself with a huge purple dildo:

    @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    @blakeyrat well, you're missing the point.

    I disagree; you yourself have said multiple times in this thread that the code needs to be fixed.

    But whatever, you obviously don't want my advice so I'll go away.

    Well, actually I was looking forward to your input, because it's .NET and I think everybody's well aware you're the go to guy for that.

    But simply saying "fix the code" is the easy way out. When this road is block, what do I do -- that's a harder question.



  • @kt_ Unblock it.


  • Dupa

    @Jaloopa said in It felt wrong but I had to rape myself with a huge purple dildo:

    Can't you use reflection to overwrite the access modifier of a method? I've never done it myself but I think I remember seeing stuff mention it

    It could well be, I'm no reflection wiz. Will have to research.

    Thanks!


  • Dupa


  • I survived the hour long Uno hand

    @kt_ Doesn't .NET have a, what's it called... friend class thing? InternalsVisibleTo, the google says?


  • SockDev

    @Yamikuronue That only applies to anything marked internal, which limits visibility to the containing assembly; protected is visible outside the assembly already



  • Seriously, though, did you try Fakes? It's a built in part of VS's unit test framework. It's really useful.


  • Dupa

    @Magus said in It felt wrong but I had to rape myself with a huge purple dildo:

    Seriously, though, did you try Fakes? It's a built in part of VS's unit test framework. It's really useful.

    Unfortunately, we're all on VS 2013 Pro and fakes seem to be available on Premium and Ultimate.



  • @kt_ ah well, sometimes cheapness wins. Sucks to be you.


  • Dupa

    Ok, so I went to work today with an idea how to do this shit the right way, using moq. However, everything went to shit at the very beginning. You see, those methods are not just simple validators -- their names start with ValidateAndUpdate and there's a reason for it -- everything's passed ByRef there (yeah, even reference types). And moq can't attach itself to protected methods receiving parameters ByRef.

    So bye-bye, good intentions, it must be written this shitty way.

    Fuck this shit!



  • @kt_ Well have fun writing your pointless code for dumb reasons.


  • Dupa

    @Magus said in It felt wrong but I had to rape myself with a huge purple dildo:

    @kt_ ah well, sometimes cheapness wins. Sucks to be you.

    Yeah, we have this saying in Polish: you can't jump higher than your ass.



  • @kt_ said in It felt wrong but I had to rape myself with a huge purple dildo:

    we're all on VS 2013 Pro

    Lucky you. We're on VS2008.



  • @kt_

    At this point... just burn shit.

    Because whatever beast you have to write to test the production is going to be a case of "who watches the watchmen".

    @blakeyrat said in It felt wrong but I had to rape myself with a huge purple dildo:

    Look; you're focused on the wrong thing. What's the goal of your adding tests? Is it just to check off "100% test coverage" on some consultant's Excel spreadsheet, or is it to increase the quality of your code?
    If the former, then yes, do whatever.
    If the latter, then rewriting that class is advancing your goal.

    So much this...



  • @blakeyrat Correct me if I am wrong, but in most corporate structures, one has to have the authority and authorization to make significant changes to a code base, regardless of the purpose, right? It sounds to me that the real stumbling block is that someone higher in the chain is mandating that everyone use this God class for raisins, and that no one transplant a good heart in place of this dying one, and @kt_ doesn't have the juice to even propose the required changes for sanity to prevail, never mind implement them.



  • @ScholRLEA said in It felt wrong but I had to rape myself with a huge purple dildo:

    @blakeyrat Correct me if I am wrong, but in most corporate structures, one has to have the authority and authorization to make significant changes to a code base, regardless of the purpose, right? It sounds to me that the real stumbling block is that someone higher in the chain is mandating that everyone use this God class for raisins, and @kt_ doesn't have the juice to even propose the required changes for sanity to prevail, never mind implement them.

    Time to vote with your feet.

    If they insist on 100% test coverage over that nonsense, then it's just a checklist.



  • @xaade Agreed. The only way to win is not to play. Fire up your resume tool and escape while you can.



  • @kt_

    Have you tried....

    Backflip.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.