简体   繁体   English

如何模拟 NpgsqlTransaction 和 NpgsqlConnection?

[英]how to mock NpgsqlTransaction and NpgsqlConnection?

I am currently trying to write unittest for method such as this我目前正在尝试为这样的方法编写单元测试

    public bool SaveSchema(Schema newSchema, NpgsqlTransaction transaction)

and the properties being parsed the method is a Schema, and a NpgsqlTransaction transaction.正在解析的属性是一个 Schema 和一个 NpgsqlTransaction 事务。 The schema can easily be generated, as it code I have full access to but the transaction is a bit of a different story.模式可以轻松生成,因为我可以完全访问它的代码,但交易有点不同。

I cannot seem to figure out a good way of mocking this?我似乎想不出一个嘲笑这个的好方法?

I tried writing wrapper for it, but NpgsqlTransaction don't have a public constructor, so it is not possible to make one, or I end up writing the entire thing twice我尝试为它编写包装器,但是 NpgsqlTransaction 没有公共构造函数,所以不可能制作一个,或者我最终将整个东西写了两次

here is my attempt - isn't there no better way of mocking the NpgsqlTransaction?这是我的尝试 - 没有更好的方法来模拟 NpgsqlTransaction 吗?

   public class NpgsqlConnectionAdapter : INpgsqlConnectionAdapter
    {
        private readonly NpgsqlConnection npgsqlConnection;

        public NpgsqlConnectionAdapter()
        {
            npgsqlConnection = new();
        }

        public NpgsqlTransaction BeginTransaction()
        {
            return npgsqlConnection.BeginTransaction();
        }

        public void Commit()
        {

        }

    }

    public class NpgsqlTransactionAdapter : INpgsqlTransactionAdapter
    {

        private readonly NpgsqlTransaction npgsqlTransaction;

        public void Commit()
        {
            npgsqlTransaction.Commit();
        }

    }

    public interface INpgsqlConnectionAdapter
    {

    }

    public interface INpgsqlTransactionAdapter
    {

    }

Mocking your database is a huge effort and probably worthless in the end.模拟您的数据库是一项巨大的努力,最终可能毫无价值。 You will find that you spent more time on mocking extremely complicated things and you gain nothing, because you still don't know if your actual statements would really work on a real database.你会发现你花了更多的时间在模拟极其复杂的事情上,却一无所获,因为你仍然不知道你的实际语句是否真的适用于真正的数据库。

The way to go here is to write your database layer as technology agnostic as possible.这里的方法是尽可能将您的数据库层编写为技术不可知的。 For example, you should use IDbConnection and IDbTransaction in your code and only have single point where you actually decide that it's a NpgsqlConnection with a specific connection string in production.例如,你应该在你的代码中使用IDbConnectionIDbTransaction并且只有一个点你实际上决定它是一个NpgsqlConnection在生产中具有特定的连接字符串。

That way for your unit tests you only need to change a single line, and tell it to (for example) use an Sqlite in-memory database instead.这样对于您的单元测试,您只需要更改一行,并告诉它(例如)改用 Sqlite 内存数据库。 Now you can unit test with a real database, but one that is self-contained to this test only.现在您可以使用真实数据库进行单元测试,但该数据库仅适用于该测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM