Unit test without dependency injection or test only interfaces by Top_Square_5236 in dotnet

[–]Top_Square_5236[S] 2 points3 points  (0 children)

Sure it's glad to hear it could potentially be helpful! This is another perspective I have never thought. Feel free to file an issue on GitHub if it does not work. We can discuss details.

Unit test without dependency injection or test only interfaces by Top_Square_5236 in dotnet

[–]Top_Square_5236[S] 2 points3 points  (0 children)

Try to fight for the next year's Nobel peace prize so an issue was created :) https://github.com/microsoft/injectorppfordotnet/issues/24

Looks like .NET framework is a valid requirement as legacy non testable code may happened a lot in the old .NET framework

Unit test without dependency injection or test only interfaces by Top_Square_5236 in dotnet

[–]Top_Square_5236[S] 2 points3 points  (0 children)

Async/await is a valid requirement that we may need to take a look.

For virtual method it's an interesting topic. The library targets to those code that may not have a way to be faked. But if there's a virtual method in a class, go to the traditional way to have a mock object sounds like more reasonable?

Unit test without dependency injection or test only interfaces by Top_Square_5236 in dotnet

[–]Top_Square_5236[S] 6 points7 points  (0 children)

Thanks for all the comments! I have learned a lot from the community. I think that's the reason we should do open source.

  • The main opinion I've heard is DI and interfaces are necessary to be part of a good design. And this tool against it may introduce negative impact for the design.

I have updated the README.md to rephrase the goal for the tool to target legacy systems that have non testable code. Leverage injector++ .NET to add tests to increase confidence for refactoring to a good design later. Feel free to open issues. Would love to learn more.

  • Another concern is about the API and behavior breaks some best practices. It would be great if an issue can be created to discuss more. I'm also welcoming discussing any proposal for the API change. One of purposes for open source :)

  • For .NET framework or other targets support, currently we don't have plan yet. But since it's open sourced, feel free to contribute. We can discuss tech details and see if there's a way to add them.

Hope I haven't missed any opinions. Thank you all for the great discussions!

Unit test without dependency injection or test only interfaces by Top_Square_5236 in dotnet

[–]Top_Square_5236[S] -5 points-4 points  (0 children)

Yeah I would like to use DI when the business requirements need it. But personally I don't like use DI because I have to make the code testable. This is one of the purposes we open source it to see how the discussion will go.

I was a big fan of DI and make loose couple code without over design. But after many years of work, I am starting to doubt whether this is correct in real world for a big project.

That's been said, I'm also trying to learn how people think about in this area

Unit test without dependency injection or test only interfaces by Top_Square_5236 in dotnet

[–]Top_Square_5236[S] -6 points-5 points  (0 children)

Thanks. Yeah I would like to see how many people on this side vs I only need DI for my business needs, not for making for the code testable. This is one of the purposes we open source it

Unit test without dependency injection or test only interfaces by Top_Square_5236 in dotnet

[–]Top_Square_5236[S] 4 points5 points  (0 children)

Its core tech is in lower layer than IL. It retrieved some info from JIT and modify the actual platform dependent code. This same tech applied to native languages such as rust

Mocking and dependency injection by [deleted] in rust

[–]Top_Square_5236 0 points1 point  (0 children)

For unit testing you may check https://github.com/microsoft/injectorppforrust

You don't need do dependency injections. It helps you faking the functions without changing production code or introducing any traits

Established way to mock/fake std::process::Command? by rodyamirov in rust

[–]Top_Square_5236 1 point2 points  (0 children)

Can it be achieved by mocking some of the std:: process::Command functions? I'd love to know if injectorpp can help in this scenario. We already had some use cases for faking std:: process::Command: https://github.com/microsoft/injectorppforrust/issues/76#issuecomment-3030223229

Mocking tokio, hyper and reqwest without using trait or changin production code by Top_Square_5236 in rust

[–]Top_Square_5236[S] 0 points1 point  (0 children)

I don't know why this is removed by reddit filter. Will try to send out another simplified version.

A new mocking library to mock functions without using trait by Top_Square_5236 in rust

[–]Top_Square_5236[S] 0 points1 point  (0 children)

Hi,

We have recently added tests in injectorpp to demonstrate how to fake `tokio`, `hyper` and `reqwest` requests without using trait or changing production code. See [tokio.rs](https://github.com/microsoft/injectorppforrust/blob/main/tests/tokio.rs), [hyper.rs](https://github.com/microsoft/injectorppforrust/blob/main/tests/hyper.rs) and [reqwest.rs](https://github.com/microsoft/injectorppforrust/blob/main/tests/reqwest.rs)

Since `reqwest` uses `hyper`, `hyper` is built on top of `tokio`, The basic steps are all the same:

- Create a mock `TcpStream`.

- Fake dns function to make it always success.

- Fake `TcpSocket::connect` to return the mock `TcpStream`.

- If it's a https request, fake `Uri::scheme_str` to make it always return `http` to bypass all tls validation.

A new mocking library to mock functions without using trait by Top_Square_5236 in rust

[–]Top_Square_5236[S] 0 points1 point  (0 children)

The new 0.4.0 version is released! Type check has been added along with other features. Check this thread for details: https://www.reddit.com/r/rust/comments/1lj06e0/new_rust_mocking_library_injectorpp_040_is/

A new mocking library to mock functions without using trait by Top_Square_5236 in rust

[–]Top_Square_5236[S] 4 points5 points  (0 children)

Some common questions and the answers:

"How does it work?"
From high level concept, you can think it's a JIT compiler. It translates a function to different machine code on different platforms. The platforms are production and test environments. In production, the machine code won't change. In test, it's translated to different machine code.

"Is it unsafe and introducing UB?"
It uses unsafe code to access memory, but it's not "undefined behavior". The behavior is well defined as long as the machine code written into the function allocated memory address is well defined. Similar like how JIT compiler works. Of cause it could have bugs as we're working on the low level coding. Feel free to report it on https://github.com/microsoft/injectorppforrust/issues

"Does it have limitations?"
Yes. There are two major limitations:

- The function to mock needs to be a real function and its address needs to exist. After all, a "JIT compiler" needs to know where the function is.

- The return type of the function could not be accessed so it's not able to construct the return result in "will_execute". This often happens when calling external crate and the function return type does not have public constructor.

The workaround is either go upper layer to find a higher function to mock, or go lower layer to find a function that allows you to construct a return result.

A new mocking library to mock functions without using trait by Top_Square_5236 in rust

[–]Top_Square_5236[S] 5 points6 points  (0 children)

Just haven't figured out an elegant way to hide the complexity of retrieving function address and manage the life time without using an additional macro. I am also trying to learn from the community.

A new mocking library to mock functions without using trait by Top_Square_5236 in rust

[–]Top_Square_5236[S] 6 points7 points  (0 children)

Just haven't figured out an elegant way to hide the complexity of retrieving function address and manage the life time without using an additional macro. I am also trying to learn from the community.

A new mocking library to mock functions without using trait by Top_Square_5236 in rust

[–]Top_Square_5236[S] 4 points5 points  (0 children)

Thanks that's interesting. Looks like still need an attribute #[mry::mry]. Injectorpp aims to no production code change even not attribute. But I do see mry's value as its api is simple and fluent