c#中的iStringLocalizerFactory thr throw nullReferenceException

发布于 2025-02-07 14:43:57 字数 2199 浏览 1 评论 0原文

我正在尝试为使用IstringLocalizerFactory翻译字符串的服务编写测试。所有翻译都在一个资源文件中。我似乎无法为它起作用的模拟,因为它总是抛出nullreferenceException。调试时,它表明_localizer为空。当我完全删除本地化逻辑时,测试成功。

我正在尝试测试的代码:

        private readonly IStringLocalizer _localizer;

        public EventService(IEventRepository eventRepository, IMemberEventRepository memberEventRepository, IStringLocalizerFactory factory)
        {

            this._eventRepository = eventRepository;
            this._memberEventRepository = memberEventRepository;
            this._localizer = factory.Create(typeof(Resource));
        }

        public async Task CreateEventRegistrationAsync(MemberEvent entity)
        {
            if (await this._memberEventRepository.GetMemberEvent(entity.EventId, entity.MemberId) != null)
            {
                throw new ArgumentException(_localizer["This member already participates in this event."].Value);
            }

            await this._memberEventRepository.CreateAsync(entity);
        }

我的测试:

        private Mock<IStringLocalizerFactory> _stringLocalizerFactoryMock = new Mock<IStringLocalizerFactory>();

        public EventServiceTests()
        {
            _service = new EventService(_eventRepoMock.Object, _memberEventRepoMock.Object, _stringLocalizerFactoryMock.Object);
        }

        [Fact]
        public async Task CreateEventRegistrationAsync_ShouldThrowArgumentException_WhenMemberAlreadyRegisteredForEvent()
        {
            int eventId = 456;
            int memberId = 123;

            _stringLocalizerFactoryMock.Setup(x => x.Create(typeof(Resource)))
                .Returns(() => new StringLocalizer<Resource>(_stringLocalizerFactoryMock.Object));

            MemberEvent registration = new MemberEvent
            {
                EventId = eventId,
                MemberId = memberId
            };

            _memberEventRepoMock.Setup(x => x.GetMemberEvent(eventId, memberId))
                .ReturnsAsync(registration);
            
            await Assert.ThrowsAsync<ArgumentException>(async () => await _service.CreateEventRegistrationAsync(registration));
        }

I'm trying to write a test for a service that uses IStringLocalizerFactory to translate strings. All of the translations are in a single Resource file. I cannot seem to get the Mock for it to work, as it always throws a NullReferenceException. When debugging, it shows that _localizer is null. When I remove the localizer logic completely, the test succeeds.

Code I'm trying to test:

        private readonly IStringLocalizer _localizer;

        public EventService(IEventRepository eventRepository, IMemberEventRepository memberEventRepository, IStringLocalizerFactory factory)
        {

            this._eventRepository = eventRepository;
            this._memberEventRepository = memberEventRepository;
            this._localizer = factory.Create(typeof(Resource));
        }

        public async Task CreateEventRegistrationAsync(MemberEvent entity)
        {
            if (await this._memberEventRepository.GetMemberEvent(entity.EventId, entity.MemberId) != null)
            {
                throw new ArgumentException(_localizer["This member already participates in this event."].Value);
            }

            await this._memberEventRepository.CreateAsync(entity);
        }

My tests:

        private Mock<IStringLocalizerFactory> _stringLocalizerFactoryMock = new Mock<IStringLocalizerFactory>();

        public EventServiceTests()
        {
            _service = new EventService(_eventRepoMock.Object, _memberEventRepoMock.Object, _stringLocalizerFactoryMock.Object);
        }

        [Fact]
        public async Task CreateEventRegistrationAsync_ShouldThrowArgumentException_WhenMemberAlreadyRegisteredForEvent()
        {
            int eventId = 456;
            int memberId = 123;

            _stringLocalizerFactoryMock.Setup(x => x.Create(typeof(Resource)))
                .Returns(() => new StringLocalizer<Resource>(_stringLocalizerFactoryMock.Object));

            MemberEvent registration = new MemberEvent
            {
                EventId = eventId,
                MemberId = memberId
            };

            _memberEventRepoMock.Setup(x => x.GetMemberEvent(eventId, memberId))
                .ReturnsAsync(registration);
            
            await Assert.ThrowsAsync<ArgumentException>(async () => await _service.CreateEventRegistrationAsync(registration));
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黑寡妇 2025-02-14 14:43:57

通过检查正在测试的主题,我可以看到

_localizer["This member already participates in this event."].Value 

会引发无效的异常,因为_localizer [...]未设置,因此当调用.value时失败。

考虑嘲笑iStringLocalizer&lt; t&gt;,以便在调用测试时可以按预期进行设置。

//...

var localizer = new Mock<IStringLocalizer<Resource>>();

localizer
    .Setup(_ => _[It.IsAny<string>()])
    .Returns(string key => new LocalizedString(key, key));

_stringLocalizerFactoryMock
    .Setup(_ => _.Create(It.IsAny<Type>()))
    .Returns(() => localizer.Object));

//...

From examining the subject under test I see that

_localizer["This member already participates in this event."].Value 

will throw a null exception because _localizer[...] was not setup and thus fail when .Value is invoked.

Consider mocking a IStringLocalizer<T> so that it can be setup to behave as expected when the test is invoked.

//...

var localizer = new Mock<IStringLocalizer<Resource>>();

localizer
    .Setup(_ => _[It.IsAny<string>()])
    .Returns(string key => new LocalizedString(key, key));

_stringLocalizerFactoryMock
    .Setup(_ => _.Create(It.IsAny<Type>()))
    .Returns(() => localizer.Object));

//...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文